From 340f4fc5508c2905a1f30de229e2a4b299d55735 Mon Sep 17 00:00:00 2001 From: Ilikara Zheng Date: Mon, 8 Dec 2025 21:23:40 +0800 Subject: [PATCH 001/102] nvme-pci: disable secondary temp for Wodposit WPBSNM8 Secondary temperature thresholds (temp2_{min,max}) were not reported properly on this NVMe SSD. This resulted in an error while attempting to read these values with sensors(1): ERROR: Can't get value of subfeature temp2_min: I/O error ERROR: Can't get value of subfeature temp2_max: I/O error Add the device to the nvme_id_table with the NVME_QUIRK_NO_SECONDARY_TEMP_THRESH flag to suppress access to all non- composite temperature thresholds. Cc: stable@vger.kernel.org Tested-by: Wu Haotian Signed-off-by: Ilikara Zheng Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 0e4caeab739c..29e715d5b8f3 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3999,6 +3999,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x1fa0, 0x2283), /* Wodposit WPBSNM8-256GTP */ + .driver_data = NVME_QUIRK_NO_SECONDARY_TEMP_THRESH, }, { PCI_DEVICE(0x025e, 0xf1ac), /* SOLIDIGM P44 pro SSDPFKKW020X7 */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0xc0a9, 0x540a), /* Crucial P2 */ From 9bd18e1262c0fec6d76ffe6e2eae2b5f6cc08e3e Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Fri, 12 Dec 2025 13:45:20 +0100 Subject: [PATCH 002/102] printk/nbcon: Restore IRQ in atomic flush after each emitted record The commit d5d399efff6577 ("printk/nbcon: Release nbcon consoles ownership in atomic flush after each emitted record") prevented stall of a CPU which lost nbcon console ownership because another CPU entered an emergency flush. But there is still the problem that the CPU doing the emergency flush might cause a stall on its own. Let's go even further and restore IRQ in the atomic flush after each emitted record. It is not a complete solution. The interrupts and/or scheduling might still be blocked when the emergency atomic flush was called with IRQs and/or scheduling disabled. But it should remove the following lockup: mlx5_core 0000:03:00.0: Shutdown was called kvm: exiting hardware virtualization arm-smmu-v3 arm-smmu-v3.10.auto: CMD_SYNC timeout at 0x00000103 [hwprod 0x00000104, hwcons 0x00000102] smp: csd: Detected non-responsive CSD lock (#1) on CPU#4, waiting 5000000032 ns for CPU#00 do_nothing (kernel/smp.c:1057) smp: csd: CSD lock (#1) unresponsive. [...] Call trace: pl011_console_write_atomic (./arch/arm64/include/asm/vdso/processor.h:12 drivers/tty/serial/amba-pl011.c:2540) (P) nbcon_emit_next_record (kernel/printk/nbcon.c:1049) __nbcon_atomic_flush_pending_con (kernel/printk/nbcon.c:1517) __nbcon_atomic_flush_pending.llvm.15488114865160659019 (./arch/arm64/include/asm/alternative-macros.h:254 ./arch/arm64/include/asm/cpufeature.h:808 ./arch/arm64/include/asm/irqflags.h:192 kernel/printk/nbcon.c:1562 kernel/printk/nbcon.c:1612) nbcon_atomic_flush_pending (kernel/printk/nbcon.c:1629) printk_kthreads_shutdown (kernel/printk/printk.c:?) syscore_shutdown (drivers/base/syscore.c:120) kernel_kexec (kernel/kexec_core.c:1045) __arm64_sys_reboot (kernel/reboot.c:794 kernel/reboot.c:722 kernel/reboot.c:722) invoke_syscall (arch/arm64/kernel/syscall.c:50) el0_svc_common.llvm.14158405452757855239 (arch/arm64/kernel/syscall.c:?) do_el0_svc (arch/arm64/kernel/syscall.c:152) el0_svc (./arch/arm64/include/asm/alternative-macros.h:254 ./arch/arm64/include/asm/cpufeature.h:808 ./arch/arm64/include/asm/irqflags.h:73 arch/arm64/kernel/entry-common.c:169 arch/arm64/kernel/entry-common.c:182 arch/arm64/kernel/entry-common.c:749) el0t_64_sync_handler (arch/arm64/kernel/entry-common.c:820) el0t_64_sync (arch/arm64/kernel/entry.S:600) In this case, nbcon_atomic_flush_pending() is called from printk_kthreads_shutdown() with IRQs and scheduling enabled. Note that __nbcon_atomic_flush_pending_con() is directly called also from nbcon_device_release() where the disabled IRQs might break PREEMPT_RT guarantees. But the atomic flush is called only in emergency or panic situations where the latencies are irrelevant anyway. An ultimate solution would be a touching of watchdogs. But it would hide all problems. Let's do it later when anyone reports a stall which does not have a better solution. Closes: https://lore.kernel.org/r/sqwajvt7utnt463tzxgwu2yctyn5m6bjwrslsnupfexeml6hkd@v6sqmpbu3vvu Tested-by: Breno Leitao Reviewed-by: John Ogness Link: https://patch.msgid.link/20251212124520.244483-1-pmladek@suse.com Signed-off-by: Petr Mladek --- kernel/printk/nbcon.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 3fa403f9831f..32fc12e53675 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1557,18 +1557,27 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) ctxt->allow_unsafe_takeover = nbcon_allow_unsafe_takeover(); while (nbcon_seq_read(con) < stop_seq) { - if (!nbcon_context_try_acquire(ctxt, false)) - return -EPERM; - /* - * nbcon_emit_next_record() returns false when the console was - * handed over or taken over. In both cases the context is no - * longer valid. + * Atomic flushing does not use console driver synchronization + * (i.e. it does not hold the port lock for uart consoles). + * Therefore IRQs must be disabled to avoid being interrupted + * and then calling into a driver that will deadlock trying + * to acquire console ownership. */ - if (!nbcon_emit_next_record(&wctxt, true)) - return -EAGAIN; + scoped_guard(irqsave) { + if (!nbcon_context_try_acquire(ctxt, false)) + return -EPERM; - nbcon_context_release(ctxt); + /* + * nbcon_emit_next_record() returns false when + * the console was handed over or taken over. + * In both cases the context is no longer valid. + */ + if (!nbcon_emit_next_record(&wctxt, true)) + return -EAGAIN; + + nbcon_context_release(ctxt); + } if (!ctxt->backlog) { /* Are there reserved but not yet finalized records? */ @@ -1595,22 +1604,11 @@ static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq) { struct console_flush_type ft; - unsigned long flags; int err; again: - /* - * Atomic flushing does not use console driver synchronization (i.e. - * it does not hold the port lock for uart consoles). Therefore IRQs - * must be disabled to avoid being interrupted and then calling into - * a driver that will deadlock trying to acquire console ownership. - */ - local_irq_save(flags); - err = __nbcon_atomic_flush_pending_con(con, stop_seq); - local_irq_restore(flags); - /* * If there was a new owner (-EPERM, -EAGAIN), that context is * responsible for completing. From 49aadf830eb048134d33ad7329d92ecff45d8dbb Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jan 2026 12:14:10 +0100 Subject: [PATCH 003/102] ASoC: codecs: wsa883x: fix unnecessary initialisation The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. This avoids repeated initialisation of the codecs during boot of machines like the Lenovo ThinkPad X13s: [ 11.614523] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.618022] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.621377] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.624065] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.631382] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.634424] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") Cc: stable@vger.kernel.org # 6.0 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-2-johan@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index c3046e260cb9..3ffea56aeb0f 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -475,6 +475,7 @@ struct wsa883x_priv { int active_ports; int dev_mode; int comp_offset; + bool hw_init; /* * Protects temperature reading code (related to speaker protection) and * fields: temperature and pa_on. @@ -1043,6 +1044,9 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x) struct regmap *regmap = wsa883x->regmap; int variant, version, ret; + if (wsa883x->hw_init) + return 0; + ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant); if (ret) return ret; @@ -1085,6 +1089,8 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x) wsa883x->comp_offset); } + wsa883x->hw_init = true; + return 0; } @@ -1093,6 +1099,9 @@ static int wsa883x_update_status(struct sdw_slave *slave, { struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev); + if (status == SDW_SLAVE_UNATTACHED) + wsa883x->hw_init = false; + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) return wsa883x_init(wsa883x); From 29d71b8a5a40708b3eed9ba4953bfc2312c9c776 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jan 2026 12:14:11 +0100 Subject: [PATCH 004/102] ASoC: codecs: wsa881x: fix unnecessary initialisation The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. Fixes: a0aab9e1404a ("ASoC: codecs: add wsa881x amplifier support") Cc: stable@vger.kernel.org # 5.6 Cc: Srinivas Kandagatla Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-3-johan@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa881x.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index d7aca6567c2d..2fc234adca5f 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -678,6 +678,7 @@ struct wsa881x_priv { */ unsigned int sd_n_val; int active_ports; + bool hw_init; bool port_prepared[WSA881X_MAX_SWR_PORTS]; bool port_enable[WSA881X_MAX_SWR_PORTS]; }; @@ -687,6 +688,9 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x) struct regmap *rm = wsa881x->regmap; unsigned int val = 0; + if (wsa881x->hw_init) + return; + regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0, ARRAY_SIZE(wsa881x_rev_2_0)); @@ -724,6 +728,8 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x) regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A); regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2); regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05); + + wsa881x->hw_init = true; } static int wsa881x_component_probe(struct snd_soc_component *comp) @@ -1067,6 +1073,9 @@ static int wsa881x_update_status(struct sdw_slave *slave, { struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev); + if (status == SDW_SLAVE_UNATTACHED) + wsa881x->hw_init = false; + if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0) wsa881x_init(wsa881x); From 120f3e6ff76209ee2f62a64e5e7e9d70274df42b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jan 2026 12:14:12 +0100 Subject: [PATCH 005/102] ASoC: codecs: wsa884x: fix codec initialisation The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED. Fix the inverted hw_init flag which was set to false instead of true after initialisation which defeats its purpose and may result in repeated unnecessary initialisation. Similarly, the initial state of the flag was also inverted so that the codec would only be initialised and brought out of regmap cache only mode if its status first transitions to UNATTACHED. Fixes: aa21a7d4f68a ("ASoC: codecs: wsa884x: Add WSA884x family of speakers") Cc: stable@vger.kernel.org # 6.5 Cc: Krzysztof Kozlowski Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Tested-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-4-johan@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa884x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index 887edd2be705..6c6b497657d0 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -1534,7 +1534,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x) wsa884x_set_gain_parameters(wsa884x); - wsa884x->hw_init = false; + wsa884x->hw_init = true; } static int wsa884x_update_status(struct sdw_slave *slave, @@ -2109,7 +2109,6 @@ static int wsa884x_probe(struct sdw_slave *pdev, /* Start in cache-only until device is enumerated */ regcache_cache_only(wsa884x->regmap, true); - wsa884x->hw_init = true; if (IS_REACHABLE(CONFIG_HWMON)) { struct device *hwmon; From 46a16d89d097ac2c93b63382a37d60aa7f21dc71 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jan 2026 12:14:13 +0100 Subject: [PATCH 006/102] ASoC: codecs: wsa883x: suppress variant printk Drivers should generally be silent on successful probe. Demote the codec variant printk to debug level and instead add a warning in case an unknown variant is ever encountered. Signed-off-by: Johan Hovold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Srinivas Kandagatla Link: https://patch.msgid.link/20260102111413.9605-5-johan@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 3ffea56aeb0f..468d2b38a22a 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1058,22 +1058,23 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x) switch (variant) { case WSA8830: - dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n", - version); + dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n", + version); break; case WSA8835: - dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n", - version); + dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n", + version); break; case WSA8832: - dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n", - version); + dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n", + version); break; case WSA8835_V2: - dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n", - version); + dev_dbg(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n", + version); break; default: + dev_warn(wsa883x->dev, "unknown variant: %d\n", variant); break; } From 12cacdfb023d1b2f6c4e5af471f2d5b6f0cbf909 Mon Sep 17 00:00:00 2001 From: Deep Harsora Date: Fri, 2 Jan 2026 15:21:24 +0000 Subject: [PATCH 007/102] ASoC: Intel: sof_sdw: Add new quirks for PTL on Dell with CS42L43 Add missing quirks for some new Dell laptops using cs42l43's speaker outputs. Signed-off-by: Deep Harsora Signed-off-by: Maciej Strozek Link: https://patch.msgid.link/20260102152132.3053106-1-mstrozek@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 2c1001148d54..8721a098d53f 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -764,6 +764,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOC_SDW_CODEC_SPKR), }, /* Pantherlake devices*/ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0DD6") + }, + .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS), + }, { .callback = sof_sdw_quirk_cb, .matches = { From 22a507d7680f2c3499c133f6384349f62f916176 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 29 Dec 2025 17:04:32 +0800 Subject: [PATCH 008/102] ASoC: simple-card-utils: Check device node before overwrite direction Even the device node don't exist, the graph_util_parse_link_direction() will overwrite the playback_only and capture_only to be zero. Which cause the playback_only and capture_only are not correct, so check device node exist or not before update the value. Signed-off-by: Shengjiu Wang Acked-by: Kuninori Morimoto Link: https://patch.msgid.link/20251229090432.3964848-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/generic/simple-card-utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 355f7ec8943c..bdc02e85b089 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -1179,9 +1179,9 @@ void graph_util_parse_link_direction(struct device_node *np, bool is_playback_only = of_property_read_bool(np, "playback-only"); bool is_capture_only = of_property_read_bool(np, "capture-only"); - if (playback_only) + if (np && playback_only) *playback_only = is_playback_only; - if (capture_only) + if (np && capture_only) *capture_only = is_capture_only; } EXPORT_SYMBOL_GPL(graph_util_parse_link_direction); From 269031b15c1433ff39e30fa7ea3ab8f0be9d6ae2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Nov 2025 15:13:50 -0800 Subject: [PATCH 009/102] x86/kaslr: Recognize all ZONE_DEVICE users as physaddr consumers Commit 7ffb791423c7 ("x86/kaslr: Reduce KASLR entropy on most x86 systems") is too narrow. The effect being mitigated in that commit is caused by ZONE_DEVICE which PCI_P2PDMA has a dependency. ZONE_DEVICE, in general, lets any physical address be added to the direct-map. I.e. not only ACPI hotplug ranges, CXL Memory Windows, or EFI Specific Purpose Memory, but also any PCI MMIO range for the DEVICE_PRIVATE and PCI_P2PDMA cases. Update the mitigation, limit KASLR entropy, to apply in all ZONE_DEVICE=y cases. Distro kernels typically have PCI_P2PDMA=y, so the practical exposure of this problem is limited to the PCI_P2PDMA=n case. A potential path to recover entropy would be to walk ACPI and determine the limits for hotplug and PCI MMIO before kernel_randomize_memory(). On smaller systems that could yield some KASLR address bits. This needs additional investigation to determine if some limited ACPI table scanning can happen this early without an open coded solution like arch/x86/boot/compressed/acpi.c needs to deploy. Cc: Ingo Molnar Cc: Kees Cook Cc: Bjorn Helgaas Cc: Peter Zijlstra Cc: Andy Lutomirski Cc: Logan Gunthorpe Cc: Andrew Morton Cc: David Hildenbrand Cc: Lorenzo Stoakes Cc: "Liam R. Howlett" Cc: Vlastimil Babka Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Michal Hocko Fixes: 7ffb791423c7 ("x86/kaslr: Reduce KASLR entropy on most x86 systems") Cc: Signed-off-by: Dan Williams Reviewed-by: Balbir Singh Tested-by: Yasunori Goto Acked-by: Dave Hansen Link: http://patch.msgid.link/692e08b2516d4_261c1100a3@dwillia2-mobl4.notmuch Signed-off-by: Dave Jiang --- arch/x86/mm/kaslr.c | 10 +++++----- drivers/pci/Kconfig | 6 ------ mm/Kconfig | 10 +++++++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c index 3c306de52fd4..834641c6049a 100644 --- a/arch/x86/mm/kaslr.c +++ b/arch/x86/mm/kaslr.c @@ -115,12 +115,12 @@ void __init kernel_randomize_memory(void) /* * Adapt physical memory region size based on available memory, - * except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the - * device BAR space assuming the direct map space is large enough - * for creating a ZONE_DEVICE mapping in the direct map corresponding - * to the physical BAR address. + * except when CONFIG_ZONE_DEVICE is enabled. ZONE_DEVICE wants to map + * any physical address into the direct-map. KASLR wants to reliably + * steal some physical address bits. Those design choices are in direct + * conflict. */ - if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb)) + if (!IS_ENABLED(CONFIG_ZONE_DEVICE) && (memory_tb < kaslr_regions[0].size_tb)) kaslr_regions[0].size_tb = memory_tb; /* diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 00b0210e1f1d..e3f848ffb52a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -225,12 +225,6 @@ config PCI_P2PDMA P2P DMA transactions must be between devices behind the same root port. - Enabling this option will reduce the entropy of x86 KASLR memory - regions. For example - on a 46 bit system, the entropy goes down - from 16 bits to 15 bits. The actual reduction in entropy depends - on the physical address bits, on processor features, kernel config - (5 level page table) and physical memory present on the system. - If unsure, say N. config PCI_LABEL diff --git a/mm/Kconfig b/mm/Kconfig index bd0ea5454af8..a992f2203eb9 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1220,10 +1220,14 @@ config ZONE_DEVICE Device memory hotplug support allows for establishing pmem, or other device driver discovered memory regions, in the memmap. This allows pfn_to_page() lookups of otherwise - "device-physical" addresses which is needed for using a DAX - mapping in an O_DIRECT operation, among other things. + "device-physical" addresses which is needed for DAX, PCI_P2PDMA, and + DEVICE_PRIVATE features among others. - If FS_DAX is enabled, then say Y. + Enabling this option will reduce the entropy of x86 KASLR memory + regions. For example - on a 46 bit system, the entropy goes down + from 16 bits to 15 bits. The actual reduction in entropy depends + on the physical address bits, on processor features, kernel config + (5 level page table) and physical memory present on the system. # # Helpers to mirror range of the CPU page tables of a process into device page From 88c72bab77aaf389beccf762e112828253ca0564 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 4 Dec 2025 10:52:26 +0100 Subject: [PATCH 010/102] cxl/region: fix format string for resource_size_t The size of this type is architecture specific, and the recommended way to print it portably is through the custom %pap format string. Fixes: d6602e25819d ("cxl/region: Add support to indicate region has extended linear cache") Signed-off-by: Arnd Bergmann Reviewed-by: Ira Weiny Reviewed-by: Dave Jiang > --- Reviewed-by: Alison Schofield Link: https://patch.msgid.link/20251204095237.1032528-1-arnd@kernel.org Signed-off-by: Dave Jiang --- drivers/cxl/core/region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index ae899f68551f..fc36a5413d3f 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -759,7 +759,7 @@ static ssize_t extended_linear_cache_size_show(struct device *dev, ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region); if ((rc = ACQUIRE_ERR(rwsem_read_intr, &rwsem))) return rc; - return sysfs_emit(buf, "%#llx\n", p->cache_size); + return sysfs_emit(buf, "%pap\n", &p->cache_size); } static DEVICE_ATTR_RO(extended_linear_cache_size); From fd9a14d233fbf33488cfa0cb7f59051b3233b017 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Mon, 5 Jan 2026 13:32:03 -0600 Subject: [PATCH 011/102] ASoC: dt-bindings: everest,es8316: Add interrupt support The Everest ES8316 has interrupt capability on its GPIO3 pin for headphone detection. Several of the RockPi 4 variants are using it already. Signed-off-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260105193203.3166320-1-robh@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/everest,es8316.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/everest,es8316.yaml b/Documentation/devicetree/bindings/sound/everest,es8316.yaml index 81a0215050e0..fe5d938ca310 100644 --- a/Documentation/devicetree/bindings/sound/everest,es8316.yaml +++ b/Documentation/devicetree/bindings/sound/everest,es8316.yaml @@ -49,6 +49,10 @@ properties: items: - const: mclk + interrupts: + maxItems: 1 + description: Headphone detect interrupt + port: $ref: audio-graph-port.yaml# unevaluatedProperties: false From 2fa0eaf78c4bb24c2b05a4db3e0d86a7dcd8fd9f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 6 Jan 2026 22:58:46 +0000 Subject: [PATCH 012/102] ASoC: ops: fix pointer types to be big-endian If manipulating big-endian data, make the pointers be big-endian instead of host-endian. This should stop the following sparse warnigns about endian-conversion: sound/soc/soc-ops.c:547:33: warning: invalid assignment: &= sound/soc/soc-ops.c:547:33: left side has type unsigned short sound/soc/soc-ops.c:547:33: right side has type restricted __be16 sound/soc/soc-ops.c:551:33: warning: invalid assignment: &= sound/soc/soc-ops.c:551:33: left side has type unsigned int sound/soc/soc-ops.c:551:33: right side has type restricted __be32 Signed-off-by: Ben Dooks Link: https://patch.msgid.link/20260106225846.83580-1-ben.dooks@codethink.co.uk Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 624e9269fc25..ba42939d5f01 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -543,11 +543,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, ucontrol->value.bytes.data[0] &= ~params->mask; break; case 2: - ((u16 *)(&ucontrol->value.bytes.data))[0] + ((__be16 *)(&ucontrol->value.bytes.data))[0] &= cpu_to_be16(~params->mask); break; case 4: - ((u32 *)(&ucontrol->value.bytes.data))[0] + ((__be32 *)(&ucontrol->value.bytes.data))[0] &= cpu_to_be32(~params->mask); break; default: From 14adddc65340f2034751c95616861c0e888e2bb1 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 14 Oct 2025 18:00:57 +0200 Subject: [PATCH 013/102] drm/bridge: dw-hdmi-qp: Fix spurious IRQ on resume After resume from suspend to RAM, the following splash is generated if the HDMI driver is probed (independent of a connected cable): [ 1194.484052] irq 80: nobody cared (try booting with the "irqpoll" option) [ 1194.484074] CPU: 0 UID: 0 PID: 627 Comm: rtcwake Not tainted 6.17.0-rc7-g96f1a11414b3 #1 PREEMPT [ 1194.484082] Hardware name: Rockchip RK3576 EVB V10 Board (DT) [ 1194.484085] Call trace: [ 1194.484087] ... (stripped) [ 1194.484283] handlers: [ 1194.484285] [<00000000bc363dcb>] dw_hdmi_qp_main_hardirq [dw_hdmi_qp] [ 1194.484302] Disabling IRQ #80 Apparently the HDMI IP is losing part of its state while the system is suspended and generates spurious interrupts during resume. The bug has not yet been noticed, as system suspend does not yet work properly on upstream kernel with either the Rockchip RK3588 or RK3576 platform. Fixes: 128a9bf8ace2 ("drm/rockchip: Add basic RK3588 HDMI output support") Signed-off-by: Sebastian Reichel Reviewed-by: Cristian Ciocaltea Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20251014-rockchip-hdmi-suspend-fix-v1-1-983fcbf44839@collabora.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 9 +++++++++ drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 12 +++++++++++- include/drm/bridge/dw_hdmi_qp.h | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index fe4c026280f0..60166919c5b5 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -163,6 +163,7 @@ struct dw_hdmi_qp { unsigned long ref_clk_rate; struct regmap *regm; + int main_irq; unsigned long tmds_char_rate; }; @@ -1271,6 +1272,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, dw_hdmi_qp_init_hw(hdmi); + hdmi->main_irq = plat_data->main_irq; ret = devm_request_threaded_irq(dev, plat_data->main_irq, dw_hdmi_qp_main_hardirq, NULL, IRQF_SHARED, dev_name(dev), hdmi); @@ -1331,9 +1333,16 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind); +void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi) +{ + disable_irq(hdmi->main_irq); +} +EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend); + void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) { dw_hdmi_qp_init_hw(hdmi); + enable_irq(hdmi->main_irq); } EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index c9fe6aa3e3e3..6e39e8a00774 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -640,6 +640,15 @@ static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev) component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops); } +static int __maybe_unused dw_hdmi_qp_rockchip_suspend(struct device *dev) +{ + struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); + + dw_hdmi_qp_suspend(dev, hdmi->hdmi); + + return 0; +} + static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) { struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev); @@ -655,7 +664,8 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev) } static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume) + SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_qp_rockchip_suspend, + dw_hdmi_qp_rockchip_resume) }; struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = { diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h index 3f461f6b9bbf..3af12f82da2c 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -34,5 +34,6 @@ struct dw_hdmi_qp_plat_data { struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, struct drm_encoder *encoder, const struct dw_hdmi_qp_plat_data *plat_data); +void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi); void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi); #endif /* __DW_HDMI_QP__ */ From d9186faeae6efb7d0841a5e8eb213ff4c7966614 Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Fri, 14 Nov 2025 14:37:03 -0600 Subject: [PATCH 014/102] drm/vmwgfx: Fix KMS with 3D on HW version 10 HW version 10 does not have GB Surfaces so there is no backing buffer for surface backed FBs. This would result in a nullptr dereference and crash the driver causing a black screen. Fixes: 965544150d1c ("drm/vmwgfx: Refactor cursor handling") Signed-off-by: Ian Forbes Reviewed-by: Zack Rusin Signed-off-by: Zack Rusin Link: https://patch.msgid.link/20251114203703.1946616-1-ian.forbes@broadcom.com --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index d32ce1cb579e..bc51b5d55e38 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -766,13 +766,15 @@ err_out: return ERR_PTR(ret); } - ttm_bo_reserve(&bo->tbo, false, false, NULL); - ret = vmw_bo_dirty_add(bo); - if (!ret && surface && surface->res.func->dirty_alloc) { - surface->res.coherent = true; - ret = surface->res.func->dirty_alloc(&surface->res); + if (bo) { + ttm_bo_reserve(&bo->tbo, false, false, NULL); + ret = vmw_bo_dirty_add(bo); + if (!ret && surface && surface->res.func->dirty_alloc) { + surface->res.coherent = true; + ret = surface->res.func->dirty_alloc(&surface->res); + } + ttm_bo_unreserve(&bo->tbo); } - ttm_bo_unreserve(&bo->tbo); return &vfb->base; } From 37a0cff4551c14aca4cfa6ef3f2f0e0f61d66825 Mon Sep 17 00:00:00 2001 From: Ian Forbes Date: Wed, 7 Jan 2026 09:20:59 -0600 Subject: [PATCH 015/102] drm/vmwgfx: Merge vmw_bo_release and vmw_bo_free functions Some of the warnings need to be reordered between these two functions in order to be correct. This has happened multiple times. Merging them solves this problem once and for all. Fixes: d6667f0ddf46 ("drm/vmwgfx: Fix handling of dumb buffers") Signed-off-by: Ian Forbes Signed-off-by: Zack Rusin Link: https://patch.msgid.link/20260107152059.3048329-1-ian.forbes@broadcom.com --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index f031a312c783..b22887e8c881 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -32,9 +32,15 @@ #include -static void vmw_bo_release(struct vmw_bo *vbo) +/** + * vmw_bo_free - vmw_bo destructor + * + * @bo: Pointer to the embedded struct ttm_buffer_object + */ +static void vmw_bo_free(struct ttm_buffer_object *bo) { struct vmw_resource *res; + struct vmw_bo *vbo = to_vmw_bo(&bo->base); WARN_ON(kref_read(&vbo->tbo.base.refcount) != 0); vmw_bo_unmap(vbo); @@ -62,20 +68,8 @@ static void vmw_bo_release(struct vmw_bo *vbo) } vmw_surface_unreference(&vbo->dumb_surface); } - drm_gem_object_release(&vbo->tbo.base); -} - -/** - * vmw_bo_free - vmw_bo destructor - * - * @bo: Pointer to the embedded struct ttm_buffer_object - */ -static void vmw_bo_free(struct ttm_buffer_object *bo) -{ - struct vmw_bo *vbo = to_vmw_bo(&bo->base); - WARN_ON(!RB_EMPTY_ROOT(&vbo->res_tree)); - vmw_bo_release(vbo); + drm_gem_object_release(&vbo->tbo.base); WARN_ON(vbo->dirty); kfree(vbo); } From bf72b4b7bb7dbb643d204fa41e7463894a95999f Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Wed, 24 Dec 2025 17:11:05 +0800 Subject: [PATCH 016/102] drm/vmwgfx: Fix an error return check in vmw_compat_shader_add() In vmw_compat_shader_add(), the return value check of vmw_shader_alloc() is not proper. Modify the check for the return pointer 'res'. Found by code review and compiled on ubuntu 20.04. Fixes: 18e4a4669c50 ("drm/vmwgfx: Fix compat shader namespace") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li Signed-off-by: Zack Rusin Link: https://patch.msgid.link/20251224091105.1569464-1-lihaoxiang@isrc.iscas.ac.cn --- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index 69dfe69ce0f8..a8c8c9375d29 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -923,8 +923,10 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, ttm_bo_unreserve(&buf->tbo); res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type); - if (unlikely(ret != 0)) + if (IS_ERR(res)) { + ret = PTR_ERR(res); goto no_reserve; + } ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader, vmw_shader_key(user_key, shader_type), From 3ea3b7891b21ce079cfc60dfd476ba59ee625a2b Mon Sep 17 00:00:00 2001 From: Bartlomiej Kubik Date: Thu, 11 Dec 2025 19:10:44 +0100 Subject: [PATCH 017/102] drm/vmwgfx: Fix kernel-doc warnings for vmwgfx_fence Add missing descriptions for vmw_event_fence_action_seq_passed. This fixes the following warnings: drivers/gpu/drm/vmwgfx/vmwgfx_fence.c:526 function parameter 'f' not described in 'vmw_event_fence_action_seq_passed' drivers/gpu/drm/vmwgfx/vmwgfx_fence.c:526 function parameter 'cb' not described in 'vmw_event_fence_action_seq_passed' Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202507040807.jKTxWGVQ-lkp@intel.com/ Signed-off-by: Bartlomiej Kubik Signed-off-by: Zack Rusin Link: https://lore.kernel.org/all/20251211181044.4098689-1-kubik.bartlomiej@gmail.com/ --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 00be92da5509..85795082fef9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -515,12 +515,12 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data, /** * vmw_event_fence_action_seq_passed * - * @action: The struct vmw_fence_action embedded in a struct - * vmw_event_fence_action. + * @f: The struct dma_fence which provides timestamp for the action event + * @cb: The struct dma_fence_cb callback for the action event. * - * This function is called when the seqno of the fence where @action is - * attached has passed. It queues the event on the submitter's event list. - * This function is always called from atomic context. + * This function is called when the seqno of the fence has passed + * and it is always called from atomic context. + * It queues the event on the submitter's event list. */ static void vmw_event_fence_action_seq_passed(struct dma_fence *f, struct dma_fence_cb *cb) From 47c27c9c9c720bc93fdc69605d0ecd9382e99047 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 7 Jan 2026 22:36:42 +0100 Subject: [PATCH 018/102] ALSA: pcm: Improve the fix for race of buffer access at PCM OSS layer Handle the error code from snd_pcm_buffer_access_lock() in snd_pcm_runtime_buffer_set_silence() function. Found by Alexandros Panagiotou Fixes: 93a81ca06577 ("ALSA: pcm: Fix race of buffer access at PCM OSS layer") Cc: stable@vger.kernel.org # 6.15 Signed-off-by: Jaroslav Kysela Link: https://patch.msgid.link/20260107213642.332954-1-perex@perex.cz Signed-off-by: Takashi Iwai --- include/sound/pcm.h | 2 +- sound/core/oss/pcm_oss.c | 4 +++- sound/core/pcm_native.c | 9 +++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 58fd6e84f961..a7860c047503 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -1402,7 +1402,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s #define snd_pcm_lib_mmap_iomem NULL #endif -void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime); +int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime); /** * snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index a82dd155e1d3..b12df5b5ddfc 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1074,7 +1074,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) runtime->oss.params = 0; runtime->oss.prepare = 1; runtime->oss.buffer_used = 0; - snd_pcm_runtime_buffer_set_silence(runtime); + err = snd_pcm_runtime_buffer_set_silence(runtime); + if (err < 0) + goto failure; runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 68bee40c9ada..932a9bf98cbc 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -730,13 +730,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime) } /* fill the PCM buffer with the current silence format; called from pcm_oss.c */ -void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime) +int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime) { - snd_pcm_buffer_access_lock(runtime); + int err; + + err = snd_pcm_buffer_access_lock(runtime); + if (err < 0) + return err; if (runtime->dma_area) snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); snd_pcm_buffer_access_unlock(runtime); + return 0; } EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence); From b7e26c8bdae70832d7c4b31ec2995b1812a60169 Mon Sep 17 00:00:00 2001 From: Matthew Schwartz Date: Thu, 8 Jan 2026 01:36:50 -0800 Subject: [PATCH 019/102] ALSA: hda/tas2781: Skip UEFI calibration on ASUS ROG Xbox Ally X There is currently an issue with UEFI calibration data parsing for some TAS devices, like the ASUS ROG Xbox Ally X (RC73XA), that causes audio quality issues such as gaps in playback. Until the issue is root caused and fixed, add a quirk to skip using the UEFI calibration data and fall back to using the calibration data provided by the DSP firmware, which restores full speaker functionality on affected devices. Cc: stable@vger.kernel.org # 6.18 Link: https://lore.kernel.org/all/160aef32646c4d5498cbfd624fd683cc@ti.com/ Closes: https://lore.kernel.org/all/0ba100d0-9b6f-4a3b-bffa-61abe1b46cd5@linux.dev/ Suggested-by: Baojun Xu Signed-off-by: Matthew Schwartz Reviewed-by: Antheas Kapenekakis Link: https://patch.msgid.link/20260108093650.1142176-1-matthew.schwartz@linux.dev Signed-off-by: Takashi Iwai --- sound/hda/codecs/side-codecs/tas2781_hda_i2c.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index f7a7f216d586..0e4bda3a544e 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -60,6 +60,7 @@ struct tas2781_hda_i2c_priv { int (*save_calibration)(struct tas2781_hda *h); int hda_chip_id; + bool skip_calibration; }; static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data) @@ -491,7 +492,8 @@ static void tasdevice_dspfw_init(void *context) /* If calibrated data occurs error, dsp will still works with default * calibrated data inside algo. */ - hda_priv->save_calibration(tas_hda); + if (!hda_priv->skip_calibration) + hda_priv->save_calibration(tas_hda); } static void tasdev_fw_ready(const struct firmware *fmw, void *context) @@ -548,6 +550,7 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, void *master_data) { struct tas2781_hda *tas_hda = dev_get_drvdata(dev); + struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv; struct hda_component_parent *parent = master_data; struct hda_component *comp; struct hda_codec *codec; @@ -573,6 +576,14 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, break; } + /* + * Using ASUS ROG Xbox Ally X (RC73XA) UEFI calibration data + * causes audio dropouts during playback, use fallback data + * from DSP firmware as a workaround. + */ + if (codec->core.subsystem_id == 0x10431384) + hda_priv->skip_calibration = true; + pm_runtime_get_sync(dev); comp->dev = dev; From 9fae82450d8a5f9c8fa016cd15186e975609b2ac Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 18 Jul 2025 14:41:13 +0800 Subject: [PATCH 020/102] drm/rockchip: vop2: Add delay between poll registers According to the implementation of read_poll_timeout_atomic, if the delay time is 0, it will only use a simple loop based on timeout_us to decrement the count. Therefore, the final timeout time will differ significantly from the set timeout time. So, here we set a specific delay time to ensure that the calculation of the timeout duration is accurate. Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568") Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20250718064120.8811-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index cd8380f0eddc..855386a6a9f5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2104,7 +2104,7 @@ static void rk3568_vop2_wait_for_port_mux_done(struct vop2 *vop2) * Spin until the previous port_mux figuration is done. */ ret = readx_poll_timeout_atomic(rk3568_vop2_read_port_mux, vop2, port_mux_sel, - port_mux_sel == vop2->old_port_sel, 0, 50 * 1000); + port_mux_sel == vop2->old_port_sel, 10, 50 * 1000); if (ret) DRM_DEV_ERROR(vop2->dev, "wait port_mux done timeout: 0x%x--0x%x\n", port_mux_sel, vop2->old_port_sel); @@ -2124,7 +2124,7 @@ static void rk3568_vop2_wait_for_layer_cfg_done(struct vop2 *vop2, u32 cfg) * Spin until the previous layer configuration is done. */ ret = readx_poll_timeout_atomic(rk3568_vop2_read_layer_cfg, vop2, atv_layer_cfg, - atv_layer_cfg == cfg, 0, 50 * 1000); + atv_layer_cfg == cfg, 10, 50 * 1000); if (ret) DRM_DEV_ERROR(vop2->dev, "wait layer cfg done timeout: 0x%x--0x%x\n", atv_layer_cfg, cfg); From 7f6721b767e219343cfe9a894f5bd869ff5b9d3a Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 18 Jul 2025 14:41:14 +0800 Subject: [PATCH 021/102] drm/rockchip: vop2: Only wait for changed layer cfg done when there is pending cfgdone bits The write of cfgdone bits always done at .atomic_flush. When userspace makes plane zpos changes of two crtc within one commit, at the .atomic_begin stage, crtcN will never receive the "layer change cfg done" event of crtcM because crtcM has not yet written "cfgdone". So only wait when there is pending cfgdone bits to avoid long timeout. Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568") Signed-off-by: Andy Yan Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20250718064120.8811-2-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 855386a6a9f5..f3950e8476a7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -2144,6 +2144,7 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) u8 layer_sel_id; unsigned int ofs; u32 ovl_ctrl; + u32 cfg_done; int i; struct vop2_video_port *vp0 = &vop2->vps[0]; struct vop2_video_port *vp1 = &vop2->vps[1]; @@ -2298,8 +2299,16 @@ static void rk3568_vop2_setup_layer_mixer(struct vop2_video_port *vp) rk3568_vop2_wait_for_port_mux_done(vop2); } - if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) - rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel); + if (layer_sel != old_layer_sel && atv_layer_sel != old_layer_sel) { + cfg_done = vop2_readl(vop2, RK3568_REG_CFG_DONE); + cfg_done &= (BIT(vop2->data->nr_vps) - 1); + cfg_done &= ~BIT(vp->id); + /* + * Changes of other VPs' overlays have not taken effect + */ + if (cfg_done) + rk3568_vop2_wait_for_layer_cfg_done(vop2, vop2->old_layer_sel); + } vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel); mutex_unlock(&vop2->ovl_lock); From 54b603f2db6b95495bc33a8f2bde80f044baff9a Mon Sep 17 00:00:00 2001 From: Yaxiong Tian Date: Tue, 30 Dec 2025 14:15:34 +0800 Subject: [PATCH 022/102] PM: EM: Fix incorrect description of the cost field in struct em_perf_state Due to commit 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove division"), the logic for energy consumption calculation has been modified. The actual calculation of cost is 10 * power * max_frequency / frequency instead of power * max_frequency / frequency. Therefore, the comment for cost has been updated to reflect the correct content. Fixes: 1b600da51073 ("PM: EM: Optimize em_cpu_energy() and remove division") Signed-off-by: Yaxiong Tian Reviewed-by: Lukasz Luba [ rjw: Added Fixes: tag ] Link: https://patch.msgid.link/20251230061534.816894-1-tianyaxiong@kylinos.cn Signed-off-by: Rafael J. Wysocki --- include/linux/energy_model.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 43aa6153dc57..e7497f804644 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -18,7 +18,7 @@ * @power: The power consumed at this level (by 1 CPU or by a registered * device). It can be a total power: static and dynamic. * @cost: The cost coefficient associated with this level, used during - * energy calculation. Equal to: power * max_frequency / frequency + * energy calculation. Equal to: 10 * power * max_frequency / frequency * @flags: see "em_perf_state flags" description below. */ struct em_perf_state { From e25348c5405c38c7b5e7b833898f2d205289186a Mon Sep 17 00:00:00 2001 From: Malaya Kumar Rout Date: Mon, 5 Jan 2026 16:07:29 +0530 Subject: [PATCH 023/102] PM: EM: Fix memory leak in em_create_pd() error path When ida_alloc() fails in em_create_pd(), the function returns without freeing the previously allocated 'pd' structure, leading to a memory leak. The 'pd' pointer is allocated either at line 436 (for CPU devices with cpumask) or line 442 (for other devices) using kzalloc(). Additionally, the function incorrectly returns -ENOMEM when ida_alloc() fails, ignoring the actual error code returned by ida_alloc(), which can fail for reasons other than memory exhaustion. Fix both issues by: 1. Freeing the 'pd' structure with kfree() when ida_alloc() fails 2. Returning the actual error code from ida_alloc() instead of -ENOMEM This ensures proper cleanup on the error path and accurate error reporting. Fixes: cbe5aeedecc7 ("PM: EM: Assign a unique ID when creating a performance domain") Signed-off-by: Malaya Kumar Rout Reviewed-by: Changwoo Min Link: https://patch.msgid.link/20260105103730.65626-1-mrout@redhat.com Signed-off-by: Rafael J. Wysocki --- kernel/power/energy_model.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 11af9f64aa82..5b055cbe5341 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -449,8 +449,10 @@ static int em_create_pd(struct device *dev, int nr_states, INIT_LIST_HEAD(&pd->node); id = ida_alloc(&em_pd_ida, GFP_KERNEL); - if (id < 0) - return -ENOMEM; + if (id < 0) { + kfree(pd); + return id; + } pd->id = id; em_table = em_table_alloc(pd); From 9ce4aef9a5b1b76207152ba019f838f62dff97b8 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 8 Jan 2026 16:07:31 +0000 Subject: [PATCH 024/102] drm/gpuvm: take GEM lock inside drm_gpuvm_bo_obtain_prealloc() When calling drm_gpuvm_bo_obtain_prealloc() and using immediate mode, this may result in a call to ops->vm_bo_free(vm_bo) while holding the GEMs gpuva mutex. This is a problem if ops->vm_bo_free(vm_bo) performs any operations that are not safe in the fence signalling critical path, and it turns out that Panthor (the only current user of the method) calls drm_gem_shmem_unpin() which takes a resv lock internally. This constitutes both a violation of signalling safety and lock inversion. To fix this, we modify the method to internally take the GEMs gpuva mutex so that the mutex can be unlocked before freeing the preallocated vm_bo. Note that this modification introduces a requirement that the driver uses immediate mode to call drm_gpuvm_bo_obtain_prealloc() as it would otherwise take the wrong lock. Fixes: 63e919a31625 ("panthor: use drm_gpuva_unlink_defer()") Reviewed-by: Boris Brezillon Signed-off-by: Alice Ryhl Link: https://patch.msgid.link/20260108-gpuvm-rust-v2-1-dbd014005a0b@google.com Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/drm_gpuvm.c | 75 ++++++++++++++++++--------- drivers/gpu/drm/panthor/panthor_mmu.c | 10 ---- 2 files changed, 51 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 8a06d296561d..0de47e83d84d 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1602,24 +1602,23 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm, } EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create); +/* + * drm_gpuvm_bo_destroy_not_in_lists() - final part of drm_gpuvm_bo cleanup + * @vm_bo: the &drm_gpuvm_bo to destroy + * + * It is illegal to call this method if the @vm_bo is present in the GEMs gpuva + * list, the extobj list, or the evicted list. + * + * Note that this puts a refcount on the GEM object, which may destroy the GEM + * object if the refcount reaches zero. It's illegal for this to happen if the + * caller holds the GEMs gpuva mutex because it would free the mutex. + */ static void -drm_gpuvm_bo_destroy(struct kref *kref) +drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo) { - struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, - kref); struct drm_gpuvm *gpuvm = vm_bo->vm; const struct drm_gpuvm_ops *ops = gpuvm->ops; struct drm_gem_object *obj = vm_bo->obj; - bool lock = !drm_gpuvm_resv_protected(gpuvm); - - if (!lock) - drm_gpuvm_resv_assert_held(gpuvm); - - drm_gpuvm_bo_list_del(vm_bo, extobj, lock); - drm_gpuvm_bo_list_del(vm_bo, evict, lock); - - drm_gem_gpuva_assert_lock_held(gpuvm, obj); - list_del(&vm_bo->list.entry.gem); if (ops && ops->vm_bo_free) ops->vm_bo_free(vm_bo); @@ -1630,6 +1629,35 @@ drm_gpuvm_bo_destroy(struct kref *kref) drm_gem_object_put(obj); } +static void +drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref) +{ + struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, + kref); + + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); +} + +static void +drm_gpuvm_bo_destroy(struct kref *kref) +{ + struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, + kref); + struct drm_gpuvm *gpuvm = vm_bo->vm; + bool lock = !drm_gpuvm_resv_protected(gpuvm); + + if (!lock) + drm_gpuvm_resv_assert_held(gpuvm); + + drm_gpuvm_bo_list_del(vm_bo, extobj, lock); + drm_gpuvm_bo_list_del(vm_bo, evict, lock); + + drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj); + list_del(&vm_bo->list.entry.gem); + + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); +} + /** * drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference * @vm_bo: the &drm_gpuvm_bo to release the reference of @@ -1745,9 +1773,7 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put_deferred); void drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm) { - const struct drm_gpuvm_ops *ops = gpuvm->ops; struct drm_gpuvm_bo *vm_bo; - struct drm_gem_object *obj; struct llist_node *bo_defer; bo_defer = llist_del_all(&gpuvm->bo_defer); @@ -1766,14 +1792,7 @@ drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm) while (bo_defer) { vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer); bo_defer = bo_defer->next; - obj = vm_bo->obj; - if (ops && ops->vm_bo_free) - ops->vm_bo_free(vm_bo); - else - kfree(vm_bo); - - drm_gpuvm_put(gpuvm); - drm_gem_object_put(obj); + drm_gpuvm_bo_destroy_not_in_lists(vm_bo); } } EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup); @@ -1861,6 +1880,9 @@ EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain); * count is decreased. If not found @__vm_bo is returned without further * increase of the reference count. * + * The provided @__vm_bo must not already be in the gpuva, evict, or extobj + * lists prior to calling this method. + * * A new &drm_gpuvm_bo is added to the GEMs gpuva list. * * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing @@ -1873,14 +1895,19 @@ drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo) struct drm_gem_object *obj = __vm_bo->obj; struct drm_gpuvm_bo *vm_bo; + drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm)); + + mutex_lock(&obj->gpuva.lock); vm_bo = drm_gpuvm_bo_find(gpuvm, obj); if (vm_bo) { - drm_gpuvm_bo_put(__vm_bo); + mutex_unlock(&obj->gpuva.lock); + kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref); return vm_bo; } drm_gem_gpuva_assert_lock_held(gpuvm, obj); list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list); + mutex_unlock(&obj->gpuva.lock); return __vm_bo; } diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index d4839d282689..f6339963e496 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -1252,17 +1252,7 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, goto err_cleanup; } - /* drm_gpuvm_bo_obtain_prealloc() will call drm_gpuvm_bo_put() on our - * pre-allocated BO if the association exists. Given we - * only have one ref on preallocated_vm_bo, drm_gpuvm_bo_destroy() will - * be called immediately, and we have to hold the VM resv lock when - * calling this function. - */ - dma_resv_lock(panthor_vm_resv(vm), NULL); - mutex_lock(&bo->base.base.gpuva.lock); op_ctx->map.vm_bo = drm_gpuvm_bo_obtain_prealloc(preallocated_vm_bo); - mutex_unlock(&bo->base.base.gpuva.lock); - dma_resv_unlock(panthor_vm_resv(vm)); op_ctx->map.bo_offset = offset; From 5b577d214fcc109707bcb77b4ae72a31cfd86798 Mon Sep 17 00:00:00 2001 From: Kery Qi Date: Wed, 7 Jan 2026 23:48:37 +0800 Subject: [PATCH 025/102] ASoC: davinci-evm: Fix reference leak in davinci_evm_probe The davinci_evm_probe() function calls of_parse_phandle() to acquire device nodes for "ti,audio-codec" and "ti,mcasp-controller". These functions return device nodes with incremented reference counts. However, in several error paths (e.g., when the second of_parse_phandle(), snd_soc_of_parse_card_name(), or devm_snd_soc_register_card() fails), the function returns directly without releasing the acquired nodes, leading to reference leaks. This patch adds an error handling path 'err_put' to properly release the device nodes using of_node_put() and clean up the pointers when an error occurs. Signed-off-by: Kery Qi Link: https://patch.msgid.link/20260107154836.1521-2-qikeyu2017@gmail.com Signed-off-by: Mark Brown --- sound/soc/ti/davinci-evm.c | 39 ++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c index 3848766d96c3..ad514c2e5a25 100644 --- a/sound/soc/ti/davinci-evm.c +++ b/sound/soc/ti/davinci-evm.c @@ -194,27 +194,32 @@ static int davinci_evm_probe(struct platform_device *pdev) return -EINVAL; dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0); - if (!dai->cpus->of_node) - return -EINVAL; + if (!dai->cpus->of_node) { + ret = -EINVAL; + goto err_put; + } dai->platforms->of_node = dai->cpus->of_node; evm_soc_card.dev = &pdev->dev; ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model"); if (ret) - return ret; + goto err_put; mclk = devm_clk_get(&pdev->dev, "mclk"); if (PTR_ERR(mclk) == -EPROBE_DEFER) { - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto err_put; } else if (IS_ERR(mclk)) { dev_dbg(&pdev->dev, "mclk not found.\n"); mclk = NULL; } drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; + if (!drvdata) { + ret = -ENOMEM; + goto err_put; + } drvdata->mclk = mclk; @@ -224,7 +229,8 @@ static int davinci_evm_probe(struct platform_device *pdev) if (!drvdata->mclk) { dev_err(&pdev->dev, "No clock or clock rate defined.\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put; } drvdata->sysclk = clk_get_rate(drvdata->mclk); } else if (drvdata->mclk) { @@ -240,8 +246,25 @@ static int davinci_evm_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&evm_soc_card, drvdata); ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card); - if (ret) + if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + goto err_put; + } + + return ret; + +err_put: + dai->platforms->of_node = NULL; + + if (dai->cpus->of_node) { + of_node_put(dai->cpus->of_node); + dai->cpus->of_node = NULL; + } + + if (dai->codecs->of_node) { + of_node_put(dai->codecs->of_node); + dai->codecs->of_node = NULL; + } return ret; } From 8dad31f85c7b91fd8bdbc6d0f27abc53bd8b1ffe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 19 Dec 2025 13:33:50 +0300 Subject: [PATCH 026/102] xfs: fix memory leak in xfs_growfs_check_rtgeom() Free the "nmp" allocation before returning -EINVAL. Fixes: dc68c0f60169 ("xfs: fix the zoned RT growfs check for zone alignment") Signed-off-by: Dan Carpenter Reviewed-by: Christoph Hellwig Signed-off-by: Carlos Maiolino --- fs/xfs/xfs_rtalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index e063f4f2f2e6..167298ad88dd 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1265,7 +1265,7 @@ xfs_growfs_check_rtgeom( uint32_t rem; if (rextsize != 1) - return -EINVAL; + goto out_inval; div_u64_rem(nmp->m_sb.sb_rblocks, gblocks, &rem); if (rem) { xfs_warn(mp, From 66b47b9c069fa548db64bde6a32d3b33aa05f740 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 8 Jan 2026 14:31:56 +0000 Subject: [PATCH 027/102] ASoC: dt-bindings: realtek,rt5640: Document mclk Commit eba5a0bac211 ("ASoC: dt-bindings: realtek,rt5640: Convert to dtschema") converted the rt5640 dt-binding to yaml format but in the process dropped 'clock' and 'clock-names' properties that are used to specify the codec 'mclk'. This is causing DTB build warnings for boards that use this codec and define an 'mclk' in device-tree. Update the rt5640 binding document to add the optional mclk. Fixes: eba5a0bac211 ("ASoC: dt-bindings: realtek,rt5640: Convert to dtschema") Signed-off-by: Jon Hunter Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260108143158.351223-2-jonathanh@nvidia.com Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/realtek,rt5640.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index 3f4f59287c1c..6bb6e12bdf8b 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -44,6 +44,14 @@ properties: - realtek,rt5640 - realtek,rt5639 + clocks: + items: + - description: phandle and clock specifier for codec MCLK. + + clock-names: + items: + - const: mclk + reg: maxItems: 1 From 25b858474497b5f7e2198f6fc9381488d9bdb55d Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 8 Jan 2026 14:31:57 +0000 Subject: [PATCH 028/102] ASoC: dt-bindings: realtek,rt5640: Update jack-detect The device-tree property 'realtek,jack-detect-source' currently only permits values from 0-6. However, commit 2b9c8d2b3c89 ("ASoC: rt5640: Add the HDA header support") updated the Realtek rt5640 to support setting the 'realtek,jack-detect-source' to 7 to support the HDA header. The Tegra234 platforms currently set 'realtek,jack-detect-source' to 7 for the HDA header and this is causing a warning when building device-tree. audio-codec@1c (realtek,rt5640): realtek,jack-detect-source: 7 is not one of [0, 1, 2, 3, 4, 5, 6] Given that the driver already supports this settings, update the binding document for the rt5640 device to add the HDA header as a valid configuration for the 'realtek,jack-detect-source' property. Fixes: 2b9c8d2b3c89 ("ASoC: rt5640: Add the HDA header support") Signed-off-by: Jon Hunter Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260108143158.351223-3-jonathanh@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/realtek,rt5640.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index 6bb6e12bdf8b..e7d4ec29b0ec 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -106,6 +106,7 @@ properties: - 4 # Use GPIO2 for jack-detect - 5 # Use GPIO3 for jack-detect - 6 # Use GPIO4 for jack-detect + - 7 # Use HDA header for jack-detect realtek,jack-detect-not-inverted: description: From b540b4e157c4b24d0501e5e50ffba598d066de42 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 8 Jan 2026 14:31:58 +0000 Subject: [PATCH 029/102] ASoC: dt-bindings: realtek,rt5640: Document port node Various boards that use the rt5640 audio codec define a 'port' child node under the codec node to describe the interface between it and the SoC that it is connected to. The binding document for the rt5640 codec does not define the 'port' child node and so this is generating warnings when running the DTB checks for these boards. Add the 'port' node to the binding document for the rt5640 codec to fix this. Signed-off-by: Jon Hunter Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260108143158.351223-4-jonathanh@nvidia.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/realtek,rt5640.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index e7d4ec29b0ec..2f6a4a6cc0e6 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -130,6 +130,10 @@ properties: - 2 # Scale current by 1.0 - 3 # Scale current by 1.5 + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + required: - compatible - reg From 32b63acd78f577b332d976aa06b56e70d054cbba Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Sat, 13 Dec 2025 13:57:48 -0500 Subject: [PATCH 030/102] nvme-tcp: fix NULL pointer dereferences in nvmet_tcp_build_pdu_iovec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length") added ttag bounds checking and data_offset validation in nvmet_tcp_handle_h2c_data_pdu(), but it did not validate whether the command's data structures (cmd->req.sg and cmd->iov) have been properly initialized before processing H2C_DATA PDUs. The nvmet_tcp_build_pdu_iovec() function dereferences these pointers without NULL checks. This can be triggered by sending H2C_DATA PDU immediately after the ICREQ/ICRESP handshake, before sending a CONNECT command or NVMe write command. Attack vectors that trigger NULL pointer dereferences: 1. H2C_DATA PDU sent before CONNECT → both pointers NULL 2. H2C_DATA PDU for READ command → cmd->req.sg allocated, cmd->iov NULL 3. H2C_DATA PDU for uninitialized command slot → both pointers NULL The fix validates both cmd->req.sg and cmd->iov before calling nvmet_tcp_build_pdu_iovec(). Both checks are required because: - Uninitialized commands: both NULL - READ commands: cmd->req.sg allocated, cmd->iov NULL - WRITE commands: both allocated Fixes: efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length") Reviewed-by: Sagi Grimberg Signed-off-by: Shivam Kumar Signed-off-by: Keith Busch --- drivers/nvme/target/tcp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 15416ff0eac4..d5966d007ba3 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -982,6 +982,18 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue) pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); goto err_proto; } + /* + * Ensure command data structures are initialized. We must check both + * cmd->req.sg and cmd->iov because they can have different NULL states: + * - Uninitialized commands: both NULL + * - READ commands: cmd->req.sg allocated, cmd->iov NULL + * - WRITE commands: both allocated + */ + if (unlikely(!cmd->req.sg || !cmd->iov)) { + pr_err("queue %d: H2CData PDU received for invalid command state (ttag %u)\n", + queue->idx, data->ttag); + goto err_proto; + } cmd->pdu_recv = 0; nvmet_tcp_build_pdu_iovec(cmd); queue->cmd = cmd; From 7d3fa7e954934fbda0a017ac1c305b7b10ecceef Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 31 Dec 2025 11:10:57 +0100 Subject: [PATCH 031/102] nvme-apple: add "apple,t8103-nvme-ans2" as compatible After discussion with the devicetree maintainers we agreed to not extend lists with the generic compatible "apple,nvme-ans2" anymore [1]. Add "apple,t8103-nvme-ans2" as fallback compatible as it is the SoC the driver and bindings were written for. [1]: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/ Cc: stable@vger.kernel.org # v6.18+ Fixes: 5bd2927aceba ("nvme-apple: Add initial Apple SoC NVMe driver") Reviewed-by: Neal Gompa Reviewed-by: Christoph Hellwig Signed-off-by: Janne Grunau Signed-off-by: Keith Busch --- drivers/nvme/host/apple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index 15b3d07f8ccd..ed61b97fde59 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -1704,6 +1704,7 @@ static const struct apple_nvme_hw apple_nvme_t8103_hw = { static const struct of_device_id apple_nvme_of_match[] = { { .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw }, + { .compatible = "apple,t8103-nvme-ans2", .data = &apple_nvme_t8103_hw }, { .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw }, {}, }; From d1877cc7270302081a315a81a0ee8331f19f95c8 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Fri, 19 Dec 2025 16:18:42 -0800 Subject: [PATCH 032/102] nvme-fc: release admin tagset if init fails nvme_fabrics creates an NVMe/FC controller in following path: nvmf_dev_write() -> nvmf_create_ctrl() -> nvme_fc_create_ctrl() -> nvme_fc_init_ctrl() nvme_fc_init_ctrl() allocates the admin blk-mq resources right after nvme_add_ctrl() succeeds. If any of the subsequent steps fail (changing the controller state, scheduling connect work, etc.), we jump to the fail_ctrl path, which tears down the controller references but never frees the admin queue/tag set. The leaked blk-mq allocations match the kmemleak report seen during blktests nvme/fc. Check ctrl->ctrl.admin_tagset in the fail_ctrl path and call nvme_remove_admin_tag_set() when it is set so that all admin queue allocations are reclaimed whenever controller setup aborts. Reported-by: Yi Zhang Reviewed-by: Justin Tee Signed-off-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- drivers/nvme/host/fc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index bc455fa98246..6948de3f438a 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3587,6 +3587,8 @@ fail_ctrl: ctrl->ctrl.opts = NULL; + if (ctrl->ctrl.admin_tagset) + nvme_remove_admin_tag_set(&ctrl->ctrl); /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); From 3e8aaacdad4f66641f87ab441fe644b45f8ebdff Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Thu, 8 Jan 2026 11:13:23 +0100 Subject: [PATCH 033/102] cxl/port: Fix target list setup for multiple decoders sharing the same dport If a switch port has more than one decoder that is using the same downstream port, the enumeration of the target lists may fail with: # dmesg | grep target.list update_decoder_targets: cxl decoder1.0: dport3 found in target list, index 3 update_decoder_targets: cxl decoder1.0: dport2 found in target list, index 2 update_decoder_targets: cxl decoder1.0: dport0 found in target list, index 0 update_decoder_targets: cxl decoder2.0: dport3 found in target list, index 1 update_decoder_targets: cxl decoder4.0: dport3 found in target list, index 1 cxl_mem mem6: failed to find endpoint12:0000:00:01.4 in target list of decoder2.1 cxl_mem mem8: failed to find endpoint13:0000:20:01.4 in target list of decoder4.1 The case, that the same downstream port can be used in multiple target lists, is allowed and possible. Fix the update of the target list. Enumerate all children of the switch port and do not stop the iteration after the first matching target was found. With the fix applied: # dmesg | grep target.list update_decoder_targets: cxl decoder1.0: dport2 found in target list, index 2 update_decoder_targets: cxl decoder1.0: dport0 found in target list, index 0 update_decoder_targets: cxl decoder1.0: dport3 found in target list, index 3 update_decoder_targets: cxl decoder2.0: dport3 found in target list, index 1 update_decoder_targets: cxl decoder2.1: dport3 found in target list, index 1 update_decoder_targets: cxl decoder4.0: dport3 found in target list, index 1 update_decoder_targets: cxl decoder4.1: dport3 found in target list, index 1 Analyzing the conditions when this happens: 1) A dport is shared by multiple decoders. 2) The decoders have interleaving configured (ways > 1). The configuration above has the following hierarchy details (fixed version): root0 |_ | | | decoder0.1 | ways: 2 | target_list: 0,1 |_______________________________________ | | | dport0 | dport1 | | port2 port4 | | |___________________ |_____________________ | | | | | | | decoder2.0 decoder2.1 | decoder4.0 decoder4.1 | ways: 2 ways: 2 | ways: 2 ways: 2 | target_list: 2,3 target_list: 2,3 | target_list: 2,3 target_list: 2,3 |___________________ |___________________ | | | | | dport2 | dport3 | dport2 | dport3 | | | | endpoint7 endpoint12 endpoint9 endpoint13 |_ |_ |_ |_ | | | | | | | | | decoder7.0 | decoder12.0 | decoder9.0 | decoder13.0 | decoder7.2 | decoder12.2 | decoder9.2 | decoder13.2 | | | | mem3 mem5 mem6 mem8 Note: Device numbers vary for every boot. Current kernel fails to enumerate endpoint12 and endpoint13 as the target list is not updated for the second decoder. Fixes: 4f06d81e7c6a ("cxl: Defer dport allocation for switch ports") Reviewed-by: Dave Jiang Reviewed-by: Alison Schofield Reviewed-by: Jonathan Cameron Signed-off-by: Robert Richter Link: https://patch.msgid.link/20260108101324.509667-1-rrichter@amd.com Signed-off-by: Dave Jiang --- drivers/cxl/core/port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index fef3aa0c6680..3310dbfae9d6 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -1590,7 +1590,7 @@ static int update_decoder_targets(struct device *dev, void *data) cxlsd->target[i] = dport; dev_dbg(dev, "dport%d found in target list, index %d\n", dport->port_id, i); - return 1; + return 0; } } From a8f49a0043011c3dd12998a6c700bb59d5365c20 Mon Sep 17 00:00:00 2001 From: "Chia-Lin Kao (AceLan)" Date: Thu, 4 Dec 2025 10:46:47 +0800 Subject: [PATCH 034/102] drm/dp: Add byte-by-byte fallback for broken USB-C adapters Some USB-C hubs and adapters have buggy firmware where multi-byte AUX reads consistently timeout, while single-byte reads from the same address work correctly. Known affected devices that exhibit this issue: - Lenovo USB-C to VGA adapter (VIA VL817 chipset) idVendor=17ef, idProduct=7217 - Dell DA310 USB-C mobile adapter hub idVendor=413c, idProduct=c010 Analysis of the failure pattern shows: - Single-byte probes to 0xf0000 (LTTPR) succeed - Single-byte probes to 0x00102 (TRAINING_AUX_RD_INTERVAL) succeed - Multi-byte reads from 0x00000 (DPCD capabilities) timeout with -ETIMEDOUT - Retrying does not help - the failure is consistent across all attempts The issue appears to be a firmware bug in the AUX transaction handling that specifically affects multi-byte reads. Add a fallback mechanism in drm_dp_dpcd_read_data() that attempts byte-by-byte reading when the normal multi-byte read fails. This workaround only activates for adapters that fail the standard read path, ensuring no impact on correctly functioning hardware. Tested with: - Lenovo USB-C to VGA adapter (VIA VL817) - now works with fallback - Dell DA310 USB-C hub - now works with fallback - Dell/Analogix Slimport adapter - continues to work with normal path Signed-off-by: Chia-Lin Kao (AceLan) Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/20251204024647.1462866-1-acelan.kao@canonical.com Signed-off-by: Mario Limonciello (AMD) --- include/drm/display/drm_dp_helper.h | 57 +++++++++++++++++++---------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index df2f24b950e4..14d2859f0bda 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -551,6 +551,22 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size); +/** + * drm_dp_dpcd_readb() - read a single byte from the DPCD + * @aux: DisplayPort AUX channel + * @offset: address of the register to read + * @valuep: location where the value of the register will be stored + * + * Returns the number of bytes transferred (1) on success, or a negative + * error code on failure. In most of the cases you should be using + * drm_dp_dpcd_read_byte() instead. + */ +static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, + unsigned int offset, u8 *valuep) +{ + return drm_dp_dpcd_read(aux, offset, valuep, 1); +} + /** * drm_dp_dpcd_read_data() - read a series of bytes from the DPCD * @aux: DisplayPort AUX channel (SST or MST) @@ -570,12 +586,29 @@ static inline int drm_dp_dpcd_read_data(struct drm_dp_aux *aux, void *buffer, size_t size) { int ret; + size_t i; + u8 *buf = buffer; ret = drm_dp_dpcd_read(aux, offset, buffer, size); - if (ret < 0) - return ret; - if (ret < size) - return -EPROTO; + if (ret >= 0) { + if (ret < size) + return -EPROTO; + return 0; + } + + /* + * Workaround for USB-C hubs/adapters with buggy firmware that fail + * multi-byte AUX reads but work with single-byte reads. + * Known affected devices: + * - Lenovo USB-C to VGA adapter (VIA VL817, idVendor=17ef, idProduct=7217) + * - Dell DA310 USB-C hub (idVendor=413c, idProduct=c010) + * Attempt byte-by-byte reading as a fallback. + */ + for (i = 0; i < size; i++) { + ret = drm_dp_dpcd_readb(aux, offset + i, &buf[i]); + if (ret < 0) + return ret; + } return 0; } @@ -609,22 +642,6 @@ static inline int drm_dp_dpcd_write_data(struct drm_dp_aux *aux, return 0; } -/** - * drm_dp_dpcd_readb() - read a single byte from the DPCD - * @aux: DisplayPort AUX channel - * @offset: address of the register to read - * @valuep: location where the value of the register will be stored - * - * Returns the number of bytes transferred (1) on success, or a negative - * error code on failure. In most of the cases you should be using - * drm_dp_dpcd_read_byte() instead. - */ -static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, - unsigned int offset, u8 *valuep) -{ - return drm_dp_dpcd_read(aux, offset, valuep, 1); -} - /** * drm_dp_dpcd_writeb() - write a single byte to the DPCD * @aux: DisplayPort AUX channel From ebabc32ddb84caf2c018ae6aeca2ca2989a8056b Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Thu, 8 Jan 2026 14:32:09 +0900 Subject: [PATCH 035/102] PM: EM: Fix yamllint warnings in the EM YNL spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The energy model YNL spec has the following two warnings when checking with yamlint: 3:1 warning missing document start "---" (document-start) 107:13 error wrong indentation: expected 10 but found 12 (indentation) So let’s fix whose lint warnings. Fixes: bd26631ccdfd ("PM: EM: Add em.yaml and autogen files") Suggested-by: Donald Hunter Reviewed-by: Lukasz Luba Reviewed-by: Donald Hunter Signed-off-by: Changwoo Min Link: https://patch.msgid.link/20260108053212.642478-2-changwoo@igalia.com Signed-off-by: Rafael J. Wysocki --- Documentation/netlink/specs/em.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/netlink/specs/em.yaml b/Documentation/netlink/specs/em.yaml index 9905ca482325..0c595a874f08 100644 --- a/Documentation/netlink/specs/em.yaml +++ b/Documentation/netlink/specs/em.yaml @@ -1,5 +1,8 @@ # SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) - +# +# Copyright (c) 2025 Valve Corporation. +# +--- name: em doc: | @@ -104,7 +107,7 @@ operations: attribute-set: pd-table event: attributes: - - pd-id + - pd-id mcgrp: event mcast-groups: From caa07a815d6ee32586beb66f67e7e3c103a02efd Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Thu, 8 Jan 2026 14:32:10 +0900 Subject: [PATCH 036/102] PM: EM: Rename em.yaml to dev-energymodel.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM YNL specification used many acronyms, including ‘em’, ‘pd’, ‘ps’, etc. While the acronyms are short and convenient, they could be confusing. So, let’s spell them out to be more specific. The following changes were made in the spec. Note that the protocol name cannot exceed GENL_NAMSIZ (16). em -> dev-energymodel pds -> perf-domains pd -> perf-domain pd-id -> perf-domain-id pd-table -> perf-table ps -> perf-state get-pds -> get-perf-domains get-pd-table -> get-perf-table pd-created -> perf-domain-created pd-updated -> perf-domain-updated pd-deleted -> perf-domain-deleted In addition. doc strings were added to the spec. based on the comments in energy_model.h. Two flag attributes (perf-state-flags and perf-domain-flags) were added for easily interpreting the bit flags. Finally, the autogenerated files and em_netlink.c were updated accordingly to reflect the name changes. Suggested-by: Donald Hunter Reviewed-by: Lukasz Luba Reviewed-by: Donald Hunter Signed-off-by: Changwoo Min Link: https://patch.msgid.link/20260108053212.642478-3-changwoo@igalia.com Signed-off-by: Rafael J. Wysocki --- .../netlink/specs/dev-energymodel.yaml | 175 ++++++++++++++++++ Documentation/netlink/specs/em.yaml | 116 ------------ MAINTAINERS | 8 +- include/uapi/linux/dev_energymodel.h | 89 +++++++++ include/uapi/linux/energy_model.h | 63 ------- kernel/power/em_netlink.c | 135 ++++++++------ kernel/power/em_netlink_autogen.c | 44 ++--- kernel/power/em_netlink_autogen.h | 20 +- 8 files changed, 384 insertions(+), 266 deletions(-) create mode 100644 Documentation/netlink/specs/dev-energymodel.yaml delete mode 100644 Documentation/netlink/specs/em.yaml create mode 100644 include/uapi/linux/dev_energymodel.h delete mode 100644 include/uapi/linux/energy_model.h diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml new file mode 100644 index 000000000000..cbc4bc38f23c --- /dev/null +++ b/Documentation/netlink/specs/dev-energymodel.yaml @@ -0,0 +1,175 @@ +# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +# +# Copyright (c) 2025 Valve Corporation. +# +--- +name: dev-energymodel + +doc: | + Energy model netlink interface to notify its changes. + +protocol: genetlink + +uapi-header: linux/dev_energymodel.h + +definitions: + - + type: flags + name: perf-state-flags + entries: + - + name: perf-state-inefficient + doc: >- + The performance state is inefficient. There is in this perf-domain, + another performance state with a higher frequency but a lower or + equal power cost. + - + type: flags + name: perf-domain-flags + entries: + - + name: perf-domain-microwatts + doc: >- + The power values are in micro-Watts or some other scale. + - + name: perf-domain-skip-inefficiencies + doc: >- + Skip inefficient states when estimating energy consumption. + - + name: perf-domain-artificial + doc: >- + The power values are artificial and might be created by platform + missing real power information. + +attribute-sets: + - + name: perf-domains + doc: >- + Information on all the performance domains. + attributes: + - + name: perf-domain + type: nest + nested-attributes: perf-domain + multi-attr: true + - + name: perf-domain + doc: >- + Information on a single performance domains. + attributes: + - + name: pad + type: pad + - + name: perf-domain-id + type: u32 + doc: >- + A unique ID number for each performance domain. + - + name: flags + type: u64 + doc: >- + Bitmask of performance domain flags. + enum: perf-domain-flags + - + name: cpus + type: string + doc: >- + CPUs that belong to this performance domain. + - + name: perf-table + doc: >- + Performance states table. + attributes: + - + name: perf-domain-id + type: u32 + doc: >- + A unique ID number for each performance domain. + - + name: perf-state + type: nest + nested-attributes: perf-state + multi-attr: true + - + name: perf-state + doc: >- + Performance state of a performance domain. + attributes: + - + name: pad + type: pad + - + name: performance + type: u64 + doc: >- + CPU performance (capacity) at a given frequency. + - + name: frequency + type: u64 + doc: >- + The frequency in KHz, for consistency with CPUFreq. + - + name: power + type: u64 + doc: >- + The power consumed at this level (by 1 CPU or by a registered + device). It can be a total power: static and dynamic. + - + name: cost + type: u64 + doc: >- + The cost coefficient associated with this level, used during energy + calculation. Equal to: power * max_frequency / frequency. + - + name: flags + type: u64 + doc: >- + Bitmask of performance state flags. + enum: perf-state-flags + +operations: + list: + - + name: get-perf-domains + attribute-set: perf-domains + doc: Get the list of information for all performance domains. + do: + reply: + attributes: + - perf-domain + - + name: get-perf-table + attribute-set: perf-table + doc: Get the energy model table of a performance domain. + do: + request: + attributes: + - perf-domain-id + reply: + attributes: + - perf-domain-id + - perf-state + - + name: perf-domain-created + doc: A performance domain is created. + notify: get-perf-table + mcgrp: event + - + name: perf-domain-updated + doc: A performance domain is updated. + notify: get-perf-table + mcgrp: event + - + name: perf-domain-deleted + doc: A performance domain is deleted. + attribute-set: perf-table + event: + attributes: + - perf-domain-id + mcgrp: event + +mcast-groups: + list: + - + name: event diff --git a/Documentation/netlink/specs/em.yaml b/Documentation/netlink/specs/em.yaml deleted file mode 100644 index 0c595a874f08..000000000000 --- a/Documentation/netlink/specs/em.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) -# -# Copyright (c) 2025 Valve Corporation. -# ---- -name: em - -doc: | - Energy model netlink interface to notify its changes. - -protocol: genetlink - -uapi-header: linux/energy_model.h - -attribute-sets: - - - name: pds - attributes: - - - name: pd - type: nest - nested-attributes: pd - multi-attr: true - - - name: pd - attributes: - - - name: pad - type: pad - - - name: pd-id - type: u32 - - - name: flags - type: u64 - - - name: cpus - type: string - - - name: pd-table - attributes: - - - name: pd-id - type: u32 - - - name: ps - type: nest - nested-attributes: ps - multi-attr: true - - - name: ps - attributes: - - - name: pad - type: pad - - - name: performance - type: u64 - - - name: frequency - type: u64 - - - name: power - type: u64 - - - name: cost - type: u64 - - - name: flags - type: u64 - -operations: - list: - - - name: get-pds - attribute-set: pds - doc: Get the list of information for all performance domains. - do: - reply: - attributes: - - pd - - - name: get-pd-table - attribute-set: pd-table - doc: Get the energy model table of a performance domain. - do: - request: - attributes: - - pd-id - reply: - attributes: - - pd-id - - ps - - - name: pd-created - doc: A performance domain is created. - notify: get-pd-table - mcgrp: event - - - name: pd-updated - doc: A performance domain is updated. - notify: get-pd-table - mcgrp: event - - - name: pd-deleted - doc: A performance domain is deleted. - attribute-set: pd-table - event: - attributes: - - pd-id - mcgrp: event - -mcast-groups: - list: - - - name: event diff --git a/MAINTAINERS b/MAINTAINERS index 765ad2daa218..1e208243b28e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9298,12 +9298,12 @@ M: Lukasz Luba M: "Rafael J. Wysocki" L: linux-pm@vger.kernel.org S: Maintained -F: kernel/power/energy_model.c -F: include/linux/energy_model.h +F: Documentation/netlink/specs/dev-energymodel.yaml F: Documentation/power/energy-model.rst -F: Documentation/netlink/specs/em.yaml -F: include/uapi/linux/energy_model.h +F: include/linux/energy_model.h +F: include/uapi/linux/dev_energymodel.h F: kernel/power/em_netlink*.* +F: kernel/power/energy_model.c EPAPR HYPERVISOR BYTE CHANNEL DEVICE DRIVER M: Laurentiu Tudor diff --git a/include/uapi/linux/dev_energymodel.h b/include/uapi/linux/dev_energymodel.h new file mode 100644 index 000000000000..3399967e1f93 --- /dev/null +++ b/include/uapi/linux/dev_energymodel.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/dev-energymodel.yaml */ +/* YNL-GEN uapi header */ +/* To regenerate run: tools/net/ynl/ynl-regen.sh */ + +#ifndef _UAPI_LINUX_DEV_ENERGYMODEL_H +#define _UAPI_LINUX_DEV_ENERGYMODEL_H + +#define DEV_ENERGYMODEL_FAMILY_NAME "dev-energymodel" +#define DEV_ENERGYMODEL_FAMILY_VERSION 1 + +/** + * enum dev_energymodel_perf_state_flags + * @DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT: The performance + * state is inefficient. There is in this perf-domain, another performance + * state with a higher frequency but a lower or equal power cost. + */ +enum dev_energymodel_perf_state_flags { + DEV_ENERGYMODEL_PERF_STATE_FLAGS_PERF_STATE_INEFFICIENT = 1, +}; + +/** + * enum dev_energymodel_perf_domain_flags + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS: The power values + * are in micro-Watts or some other scale. + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES: Skip + * inefficient states when estimating energy consumption. + * @DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL: The power values + * are artificial and might be created by platform missing real power + * information. + */ +enum dev_energymodel_perf_domain_flags { + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_MICROWATTS = 1, + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_SKIP_INEFFICIENCIES = 2, + DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL = 4, +}; + +enum { + DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN = 1, + + __DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX, + DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX - 1) +}; + +enum { + DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1, + DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, + DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS, + DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, + + __DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX, + DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAIN_MAX - 1) +}; + +enum { + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID = 1, + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE, + + __DEV_ENERGYMODEL_A_PERF_TABLE_MAX, + DEV_ENERGYMODEL_A_PERF_TABLE_MAX = (__DEV_ENERGYMODEL_A_PERF_TABLE_MAX - 1) +}; + +enum { + DEV_ENERGYMODEL_A_PERF_STATE_PAD = 1, + DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE, + DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY, + DEV_ENERGYMODEL_A_PERF_STATE_POWER, + DEV_ENERGYMODEL_A_PERF_STATE_COST, + DEV_ENERGYMODEL_A_PERF_STATE_FLAGS, + + __DEV_ENERGYMODEL_A_PERF_STATE_MAX, + DEV_ENERGYMODEL_A_PERF_STATE_MAX = (__DEV_ENERGYMODEL_A_PERF_STATE_MAX - 1) +}; + +enum { + DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS = 1, + DEV_ENERGYMODEL_CMD_GET_PERF_TABLE, + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED, + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED, + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED, + + __DEV_ENERGYMODEL_CMD_MAX, + DEV_ENERGYMODEL_CMD_MAX = (__DEV_ENERGYMODEL_CMD_MAX - 1) +}; + +#define DEV_ENERGYMODEL_MCGRP_EVENT "event" + +#endif /* _UAPI_LINUX_DEV_ENERGYMODEL_H */ diff --git a/include/uapi/linux/energy_model.h b/include/uapi/linux/energy_model.h deleted file mode 100644 index 0bcad967854f..000000000000 --- a/include/uapi/linux/energy_model.h +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ -/* Do not edit directly, auto-generated from: */ -/* Documentation/netlink/specs/em.yaml */ -/* YNL-GEN uapi header */ -/* To regenerate run: tools/net/ynl/ynl-regen.sh */ - -#ifndef _UAPI_LINUX_ENERGY_MODEL_H -#define _UAPI_LINUX_ENERGY_MODEL_H - -#define EM_FAMILY_NAME "em" -#define EM_FAMILY_VERSION 1 - -enum { - EM_A_PDS_PD = 1, - - __EM_A_PDS_MAX, - EM_A_PDS_MAX = (__EM_A_PDS_MAX - 1) -}; - -enum { - EM_A_PD_PAD = 1, - EM_A_PD_PD_ID, - EM_A_PD_FLAGS, - EM_A_PD_CPUS, - - __EM_A_PD_MAX, - EM_A_PD_MAX = (__EM_A_PD_MAX - 1) -}; - -enum { - EM_A_PD_TABLE_PD_ID = 1, - EM_A_PD_TABLE_PS, - - __EM_A_PD_TABLE_MAX, - EM_A_PD_TABLE_MAX = (__EM_A_PD_TABLE_MAX - 1) -}; - -enum { - EM_A_PS_PAD = 1, - EM_A_PS_PERFORMANCE, - EM_A_PS_FREQUENCY, - EM_A_PS_POWER, - EM_A_PS_COST, - EM_A_PS_FLAGS, - - __EM_A_PS_MAX, - EM_A_PS_MAX = (__EM_A_PS_MAX - 1) -}; - -enum { - EM_CMD_GET_PDS = 1, - EM_CMD_GET_PD_TABLE, - EM_CMD_PD_CREATED, - EM_CMD_PD_UPDATED, - EM_CMD_PD_DELETED, - - __EM_CMD_MAX, - EM_CMD_MAX = (__EM_CMD_MAX - 1) -}; - -#define EM_MCGRP_EVENT "event" - -#endif /* _UAPI_LINUX_ENERGY_MODEL_H */ diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c index 4b85da138a06..6f6238c465bb 100644 --- a/kernel/power/em_netlink.c +++ b/kernel/power/em_netlink.c @@ -12,27 +12,31 @@ #include #include #include -#include +#include #include "em_netlink.h" #include "em_netlink_autogen.h" -#define EM_A_PD_CPUS_LEN 256 +#define DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN 256 /*************************** Command encoding ********************************/ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) { - char cpus_buf[EM_A_PD_CPUS_LEN]; + char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN]; int *tot_msg_sz = data; int msg_sz, cpus_sz; cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", cpumask_pr_args(to_cpumask(pd->cpus))); - msg_sz = nla_total_size(0) + /* EM_A_PDS_PD */ - nla_total_size(sizeof(u32)) + /* EM_A_PD_PD_ID */ - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PD_FLAGS */ - nla_total_size(cpus_sz); /* EM_A_PD_CPUS */ + msg_sz = nla_total_size(0) + + /* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */ + nla_total_size(sizeof(u32)) + + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID */ + nla_total_size_64bit(sizeof(u64)) + + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS */ + nla_total_size(cpus_sz); + /* DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS */ *tot_msg_sz += nlmsg_total_size(genlmsg_msg_size(msg_sz)); return 0; @@ -40,23 +44,26 @@ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) { - char cpus_buf[EM_A_PD_CPUS_LEN]; + char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN]; struct sk_buff *msg = data; struct nlattr *entry; - entry = nla_nest_start(msg, EM_A_PDS_PD); + entry = nla_nest_start(msg, + DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN); if (!entry) goto out_cancel_nest; - if (nla_put_u32(msg, EM_A_PD_PD_ID, pd->id)) + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, + pd->id)) goto out_cancel_nest; - if (nla_put_u64_64bit(msg, EM_A_PD_FLAGS, pd->flags, EM_A_PD_PAD)) + if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_FLAGS, + pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD)) goto out_cancel_nest; snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", cpumask_pr_args(to_cpumask(pd->cpus))); - if (nla_put_string(msg, EM_A_PD_CPUS, cpus_buf)) + if (nla_put_string(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, cpus_buf)) goto out_cancel_nest; nla_nest_end(msg, entry); @@ -69,7 +76,8 @@ out_cancel_nest: return -EMSGSIZE; } -int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info) +int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, + struct genl_info *info) { struct sk_buff *msg; void *hdr; @@ -82,7 +90,7 @@ int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info) if (!msg) return -ENOMEM; - hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd); + hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd); if (!hdr) goto out_free_msg; @@ -107,10 +115,10 @@ static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs) struct em_perf_domain *pd; int id; - if (!attrs[EM_A_PD_TABLE_PD_ID]) + if (!attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]) return NULL; - id = nla_get_u32(attrs[EM_A_PD_TABLE_PD_ID]); + id = nla_get_u32(attrs[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID]); pd = em_perf_domain_get_by_id(id); return pd; } @@ -119,25 +127,34 @@ static int __em_nl_get_pd_table_size(const struct em_perf_domain *pd) { int id_sz, ps_sz; - id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */ - ps_sz = nla_total_size(0) + /* EM_A_PD_TABLE_PS */ - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_PERFORMANCE */ - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_FREQUENCY */ - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_POWER */ - nla_total_size_64bit(sizeof(u64)) + /* EM_A_PS_COST */ - nla_total_size_64bit(sizeof(u64)); /* EM_A_PS_FLAGS */ + id_sz = nla_total_size(sizeof(u32)); + /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */ + ps_sz = nla_total_size(0) + + /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE */ + nla_total_size_64bit(sizeof(u64)) + + /* DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE */ + nla_total_size_64bit(sizeof(u64)) + + /* DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY */ + nla_total_size_64bit(sizeof(u64)) + + /* DEV_ENERGYMODEL_A_PERF_STATE_POWER */ + nla_total_size_64bit(sizeof(u64)) + + /* DEV_ENERGYMODEL_A_PERF_STATE_COST */ + nla_total_size_64bit(sizeof(u64)); + /* DEV_ENERGYMODEL_A_PERF_STATE_FLAGS */ ps_sz *= pd->nr_perf_states; return nlmsg_total_size(genlmsg_msg_size(id_sz + ps_sz)); } -static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd) +static +int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain *pd) { struct em_perf_state *table, *ps; struct nlattr *entry; int i; - if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID, + pd->id)) goto out_err; rcu_read_lock(); @@ -146,24 +163,35 @@ static int __em_nl_get_pd_table(struct sk_buff *msg, const struct em_perf_domain for (i = 0; i < pd->nr_perf_states; i++) { ps = &table[i]; - entry = nla_nest_start(msg, EM_A_PD_TABLE_PS); + entry = nla_nest_start(msg, + DEV_ENERGYMODEL_A_PERF_TABLE_PERF_STATE); if (!entry) goto out_unlock_ps; - if (nla_put_u64_64bit(msg, EM_A_PS_PERFORMANCE, - ps->performance, EM_A_PS_PAD)) + if (nla_put_u64_64bit(msg, + DEV_ENERGYMODEL_A_PERF_STATE_PERFORMANCE, + ps->performance, + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) goto out_cancel_ps_nest; - if (nla_put_u64_64bit(msg, EM_A_PS_FREQUENCY, - ps->frequency, EM_A_PS_PAD)) + if (nla_put_u64_64bit(msg, + DEV_ENERGYMODEL_A_PERF_STATE_FREQUENCY, + ps->frequency, + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) goto out_cancel_ps_nest; - if (nla_put_u64_64bit(msg, EM_A_PS_POWER, - ps->power, EM_A_PS_PAD)) + if (nla_put_u64_64bit(msg, + DEV_ENERGYMODEL_A_PERF_STATE_POWER, + ps->power, + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) goto out_cancel_ps_nest; - if (nla_put_u64_64bit(msg, EM_A_PS_COST, - ps->cost, EM_A_PS_PAD)) + if (nla_put_u64_64bit(msg, + DEV_ENERGYMODEL_A_PERF_STATE_COST, + ps->cost, + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) goto out_cancel_ps_nest; - if (nla_put_u64_64bit(msg, EM_A_PS_FLAGS, - ps->flags, EM_A_PS_PAD)) + if (nla_put_u64_64bit(msg, + DEV_ENERGYMODEL_A_PERF_STATE_FLAGS, + ps->flags, + DEV_ENERGYMODEL_A_PERF_STATE_PAD)) goto out_cancel_ps_nest; nla_nest_end(msg, entry); @@ -179,7 +207,8 @@ out_err: return -EMSGSIZE; } -int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info) +int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb, + struct genl_info *info) { int cmd = info->genlhdr->cmd; int msg_sz, ret = -EMSGSIZE; @@ -197,7 +226,7 @@ int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info) if (!msg) return -ENOMEM; - hdr = genlmsg_put_reply(msg, info, &em_nl_family, 0, cmd); + hdr = genlmsg_put_reply(msg, info, &dev_energymodel_nl_family, 0, cmd); if (!hdr) goto out_free_msg; @@ -221,7 +250,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type) int msg_sz, ret = -EMSGSIZE; void *hdr; - if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT)) + if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, DEV_ENERGYMODEL_NLGRP_EVENT)) return; msg_sz = __em_nl_get_pd_table_size(pd); @@ -230,7 +259,7 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type) if (!msg) return; - hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, ntf_type); + hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, ntf_type); if (!hdr) goto out_free_msg; @@ -240,28 +269,28 @@ static void __em_notify_pd_table(const struct em_perf_domain *pd, int ntf_type) genlmsg_end(msg, hdr); - genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL); + genlmsg_multicast(&dev_energymodel_nl_family, msg, 0, + DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL); return; out_free_msg: nlmsg_free(msg); - return; } void em_notify_pd_created(const struct em_perf_domain *pd) { - __em_notify_pd_table(pd, EM_CMD_PD_CREATED); + __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_CREATED); } void em_notify_pd_updated(const struct em_perf_domain *pd) { - __em_notify_pd_table(pd, EM_CMD_PD_UPDATED); + __em_notify_pd_table(pd, DEV_ENERGYMODEL_CMD_PERF_DOMAIN_UPDATED); } static int __em_notify_pd_deleted_size(const struct em_perf_domain *pd) { - int id_sz = nla_total_size(sizeof(u32)); /* EM_A_PD_TABLE_PD_ID */ + int id_sz = nla_total_size(sizeof(u32)); /* DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID */ return nlmsg_total_size(genlmsg_msg_size(id_sz)); } @@ -272,7 +301,8 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd) void *hdr; int msg_sz; - if (!genl_has_listeners(&em_nl_family, &init_net, EM_NLGRP_EVENT)) + if (!genl_has_listeners(&dev_energymodel_nl_family, &init_net, + DEV_ENERGYMODEL_NLGRP_EVENT)) return; msg_sz = __em_notify_pd_deleted_size(pd); @@ -281,28 +311,29 @@ void em_notify_pd_deleted(const struct em_perf_domain *pd) if (!msg) return; - hdr = genlmsg_put(msg, 0, 0, &em_nl_family, 0, EM_CMD_PD_DELETED); + hdr = genlmsg_put(msg, 0, 0, &dev_energymodel_nl_family, 0, + DEV_ENERGYMODEL_CMD_PERF_DOMAIN_DELETED); if (!hdr) goto out_free_msg; - if (nla_put_u32(msg, EM_A_PD_TABLE_PD_ID, pd->id)) { + if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID, + pd->id)) goto out_free_msg; - } genlmsg_end(msg, hdr); - genlmsg_multicast(&em_nl_family, msg, 0, EM_NLGRP_EVENT, GFP_KERNEL); + genlmsg_multicast(&dev_energymodel_nl_family, msg, 0, + DEV_ENERGYMODEL_NLGRP_EVENT, GFP_KERNEL); return; out_free_msg: nlmsg_free(msg); - return; } /**************************** Initialization *********************************/ static int __init em_netlink_init(void) { - return genl_register_family(&em_nl_family); + return genl_register_family(&dev_energymodel_nl_family); } postcore_initcall(em_netlink_init); diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c index ceb3b2bb6ebe..44acef0e7df2 100644 --- a/kernel/power/em_netlink_autogen.c +++ b/kernel/power/em_netlink_autogen.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) /* Do not edit directly, auto-generated from: */ -/* Documentation/netlink/specs/em.yaml */ +/* Documentation/netlink/specs/dev-energymodel.yaml */ /* YNL-GEN kernel source */ /* To regenerate run: tools/net/ynl/ynl-regen.sh */ @@ -9,41 +9,41 @@ #include "em_netlink_autogen.h" -#include +#include -/* EM_CMD_GET_PD_TABLE - do */ -static const struct nla_policy em_get_pd_table_nl_policy[EM_A_PD_TABLE_PD_ID + 1] = { - [EM_A_PD_TABLE_PD_ID] = { .type = NLA_U32, }, +/* DEV_ENERGYMODEL_CMD_GET_PERF_TABLE - do */ +static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID + 1] = { + [DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID] = { .type = NLA_U32, }, }; -/* Ops table for em */ -static const struct genl_split_ops em_nl_ops[] = { +/* Ops table for dev_energymodel */ +static const struct genl_split_ops dev_energymodel_nl_ops[] = { { - .cmd = EM_CMD_GET_PDS, - .doit = em_nl_get_pds_doit, + .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS, + .doit = dev_energymodel_nl_get_perf_domains_doit, .flags = GENL_CMD_CAP_DO, }, { - .cmd = EM_CMD_GET_PD_TABLE, - .doit = em_nl_get_pd_table_doit, - .policy = em_get_pd_table_nl_policy, - .maxattr = EM_A_PD_TABLE_PD_ID, + .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_TABLE, + .doit = dev_energymodel_nl_get_perf_table_doit, + .policy = dev_energymodel_get_perf_table_nl_policy, + .maxattr = DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID, .flags = GENL_CMD_CAP_DO, }, }; -static const struct genl_multicast_group em_nl_mcgrps[] = { - [EM_NLGRP_EVENT] = { "event", }, +static const struct genl_multicast_group dev_energymodel_nl_mcgrps[] = { + [DEV_ENERGYMODEL_NLGRP_EVENT] = { "event", }, }; -struct genl_family em_nl_family __ro_after_init = { - .name = EM_FAMILY_NAME, - .version = EM_FAMILY_VERSION, +struct genl_family dev_energymodel_nl_family __ro_after_init = { + .name = DEV_ENERGYMODEL_FAMILY_NAME, + .version = DEV_ENERGYMODEL_FAMILY_VERSION, .netnsok = true, .parallel_ops = true, .module = THIS_MODULE, - .split_ops = em_nl_ops, - .n_split_ops = ARRAY_SIZE(em_nl_ops), - .mcgrps = em_nl_mcgrps, - .n_mcgrps = ARRAY_SIZE(em_nl_mcgrps), + .split_ops = dev_energymodel_nl_ops, + .n_split_ops = ARRAY_SIZE(dev_energymodel_nl_ops), + .mcgrps = dev_energymodel_nl_mcgrps, + .n_mcgrps = ARRAY_SIZE(dev_energymodel_nl_mcgrps), }; diff --git a/kernel/power/em_netlink_autogen.h b/kernel/power/em_netlink_autogen.h index 140ab548103c..f7e4bddcbd53 100644 --- a/kernel/power/em_netlink_autogen.h +++ b/kernel/power/em_netlink_autogen.h @@ -1,24 +1,26 @@ /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ /* Do not edit directly, auto-generated from: */ -/* Documentation/netlink/specs/em.yaml */ +/* Documentation/netlink/specs/dev-energymodel.yaml */ /* YNL-GEN kernel header */ /* To regenerate run: tools/net/ynl/ynl-regen.sh */ -#ifndef _LINUX_EM_GEN_H -#define _LINUX_EM_GEN_H +#ifndef _LINUX_DEV_ENERGYMODEL_GEN_H +#define _LINUX_DEV_ENERGYMODEL_GEN_H #include #include -#include +#include -int em_nl_get_pds_doit(struct sk_buff *skb, struct genl_info *info); -int em_nl_get_pd_table_doit(struct sk_buff *skb, struct genl_info *info); +int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, + struct genl_info *info); +int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb, + struct genl_info *info); enum { - EM_NLGRP_EVENT, + DEV_ENERGYMODEL_NLGRP_EVENT, }; -extern struct genl_family em_nl_family; +extern struct genl_family dev_energymodel_nl_family; -#endif /* _LINUX_EM_GEN_H */ +#endif /* _LINUX_DEV_ENERGYMODEL_GEN_H */ From d29b900cf412c31f18bab67d04db619f64acb43d Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Thu, 8 Jan 2026 14:32:11 +0900 Subject: [PATCH 037/102] PM: EM: Change cpus' type from string to u64 array in the EM YNL spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the cpus attribute was a string format which was a "%*pb" stringification of a bitmap. That is not very consumable for a UAPI, so let’s change it to an u64 array of CPU ids. Suggested-by: Donald Hunter Reviewed-by: Lukasz Luba Reviewed-by: Donald Hunter Signed-off-by: Changwoo Min Link: https://patch.msgid.link/20260108053212.642478-4-changwoo@igalia.com Signed-off-by: Rafael J. Wysocki --- .../netlink/specs/dev-energymodel.yaml | 3 ++- kernel/power/em_netlink.c | 22 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml index cbc4bc38f23c..af8b8f72f722 100644 --- a/Documentation/netlink/specs/dev-energymodel.yaml +++ b/Documentation/netlink/specs/dev-energymodel.yaml @@ -73,7 +73,8 @@ attribute-sets: enum: perf-domain-flags - name: cpus - type: string + type: u64 + multi-attr: true doc: >- CPUs that belong to this performance domain. - diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c index 6f6238c465bb..b6edb018c65a 100644 --- a/kernel/power/em_netlink.c +++ b/kernel/power/em_netlink.c @@ -17,17 +17,14 @@ #include "em_netlink.h" #include "em_netlink_autogen.h" -#define DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN 256 - /*************************** Command encoding ********************************/ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) { - char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN]; + int nr_cpus, msg_sz, cpus_sz; int *tot_msg_sz = data; - int msg_sz, cpus_sz; - cpus_sz = snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", - cpumask_pr_args(to_cpumask(pd->cpus))); + nr_cpus = cpumask_weight(to_cpumask(pd->cpus)); + cpus_sz = nla_total_size_64bit(sizeof(u64)) * nr_cpus; msg_sz = nla_total_size(0) + /* DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN */ @@ -44,9 +41,10 @@ static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) { - char cpus_buf[DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS_LEN]; struct sk_buff *msg = data; + struct cpumask *cpumask; struct nlattr *entry; + int cpu; entry = nla_nest_start(msg, DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN); @@ -61,10 +59,12 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) pd->flags, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD)) goto out_cancel_nest; - snprintf(cpus_buf, sizeof(cpus_buf), "%*pb", - cpumask_pr_args(to_cpumask(pd->cpus))); - if (nla_put_string(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, cpus_buf)) - goto out_cancel_nest; + cpumask = to_cpumask(pd->cpus); + for_each_cpu(cpu, cpumask) { + if (nla_put_u64_64bit(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_CPUS, + cpu, DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD)) + goto out_cancel_nest; + } nla_nest_end(msg, entry); From 380ff27af25e49e2cb2ff8fd0ecd7c95be2976ee Mon Sep 17 00:00:00 2001 From: Changwoo Min Date: Thu, 8 Jan 2026 14:32:12 +0900 Subject: [PATCH 038/102] PM: EM: Add dump to get-perf-domains in the EM YNL spec Add dump to get-perf-domains, so that a user can fetch either information about a specific performance domain with do or information about all performance domains with dump. Share the reply format of do and dump using perf-domain-attrs, so remove perf-domains. The YNL spec, autogenerated files, and the do implementation are updated, and the dump implementation is added. Suggested-by: Donald Hunter Reviewed-by: Lukasz Luba Reviewed-by: Donald Hunter Signed-off-by: Changwoo Min Link: https://patch.msgid.link/20260108053212.642478-5-changwoo@igalia.com Signed-off-by: Rafael J. Wysocki --- .../netlink/specs/dev-energymodel.yaml | 25 ++++--- include/uapi/linux/dev_energymodel.h | 7 -- kernel/power/em_netlink.c | 68 ++++++++++++++----- kernel/power/em_netlink_autogen.c | 16 ++++- kernel/power/em_netlink_autogen.h | 2 + 5 files changed, 80 insertions(+), 38 deletions(-) diff --git a/Documentation/netlink/specs/dev-energymodel.yaml b/Documentation/netlink/specs/dev-energymodel.yaml index af8b8f72f722..11faabfdfbe8 100644 --- a/Documentation/netlink/specs/dev-energymodel.yaml +++ b/Documentation/netlink/specs/dev-energymodel.yaml @@ -42,16 +42,6 @@ definitions: missing real power information. attribute-sets: - - - name: perf-domains - doc: >- - Information on all the performance domains. - attributes: - - - name: perf-domain - type: nest - nested-attributes: perf-domain - multi-attr: true - name: perf-domain doc: >- @@ -133,12 +123,21 @@ operations: list: - name: get-perf-domains - attribute-set: perf-domains + attribute-set: perf-domain doc: Get the list of information for all performance domains. do: - reply: + request: attributes: - - perf-domain + - perf-domain-id + reply: + attributes: &perf-domain-attrs + - pad + - perf-domain-id + - flags + - cpus + dump: + reply: + attributes: *perf-domain-attrs - name: get-perf-table attribute-set: perf-table diff --git a/include/uapi/linux/dev_energymodel.h b/include/uapi/linux/dev_energymodel.h index 3399967e1f93..355d8885c9a0 100644 --- a/include/uapi/linux/dev_energymodel.h +++ b/include/uapi/linux/dev_energymodel.h @@ -36,13 +36,6 @@ enum dev_energymodel_perf_domain_flags { DEV_ENERGYMODEL_PERF_DOMAIN_FLAGS_PERF_DOMAIN_ARTIFICIAL = 4, }; -enum { - DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN = 1, - - __DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX, - DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX = (__DEV_ENERGYMODEL_A_PERF_DOMAINS_MAX - 1) -}; - enum { DEV_ENERGYMODEL_A_PERF_DOMAIN_PAD = 1, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c index b6edb018c65a..5a611d3950fd 100644 --- a/kernel/power/em_netlink.c +++ b/kernel/power/em_netlink.c @@ -18,6 +18,13 @@ #include "em_netlink_autogen.h" /*************************** Command encoding ********************************/ +struct dump_ctx { + int idx; + int start; + struct sk_buff *skb; + struct netlink_callback *cb; +}; + static int __em_nl_get_pd_size(struct em_perf_domain *pd, void *data) { int nr_cpus, msg_sz, cpus_sz; @@ -43,14 +50,8 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) { struct sk_buff *msg = data; struct cpumask *cpumask; - struct nlattr *entry; int cpu; - entry = nla_nest_start(msg, - DEV_ENERGYMODEL_A_PERF_DOMAINS_PERF_DOMAIN); - if (!entry) - goto out_cancel_nest; - if (nla_put_u32(msg, DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, pd->id)) goto out_cancel_nest; @@ -66,26 +67,50 @@ static int __em_nl_get_pd(struct em_perf_domain *pd, void *data) goto out_cancel_nest; } - nla_nest_end(msg, entry); - return 0; out_cancel_nest: - nla_nest_cancel(msg, entry); - return -EMSGSIZE; } +static int __em_nl_get_pd_for_dump(struct em_perf_domain *pd, void *data) +{ + const struct genl_info *info; + struct dump_ctx *ctx = data; + void *hdr; + int ret; + + if (ctx->idx++ < ctx->start) + return 0; + + info = genl_info_dump(ctx->cb); + hdr = genlmsg_iput(ctx->skb, info); + if (!hdr) { + genlmsg_cancel(ctx->skb, hdr); + return -EMSGSIZE; + } + + ret = __em_nl_get_pd(pd, ctx->skb); + genlmsg_end(ctx->skb, hdr); + return ret; +} + int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, struct genl_info *info) { + int id, ret = -EMSGSIZE, msg_sz = 0; + int cmd = info->genlhdr->cmd; + struct em_perf_domain *pd; struct sk_buff *msg; void *hdr; - int cmd = info->genlhdr->cmd; - int ret = -EMSGSIZE, msg_sz = 0; - for_each_em_perf_domain(__em_nl_get_pd_size, &msg_sz); + if (!info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]) + return -EINVAL; + id = nla_get_u32(info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID]); + pd = em_perf_domain_get_by_id(id); + + __em_nl_get_pd_size(pd, &msg_sz); msg = genlmsg_new(msg_sz, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -94,10 +119,9 @@ int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, if (!hdr) goto out_free_msg; - ret = for_each_em_perf_domain(__em_nl_get_pd, msg); + ret = __em_nl_get_pd(pd, msg); if (ret) goto out_cancel_msg; - genlmsg_end(msg, hdr); return genlmsg_reply(msg, info); @@ -106,10 +130,22 @@ out_cancel_msg: genlmsg_cancel(msg, hdr); out_free_msg: nlmsg_free(msg); - return ret; } +int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb, + struct netlink_callback *cb) +{ + struct dump_ctx ctx = { + .idx = 0, + .start = cb->args[0], + .skb = skb, + .cb = cb, + }; + + return for_each_em_perf_domain(__em_nl_get_pd_for_dump, &ctx); +} + static struct em_perf_domain *__em_nl_get_pd_table_id(struct nlattr **attrs) { struct em_perf_domain *pd; diff --git a/kernel/power/em_netlink_autogen.c b/kernel/power/em_netlink_autogen.c index 44acef0e7df2..fedd473e4244 100644 --- a/kernel/power/em_netlink_autogen.c +++ b/kernel/power/em_netlink_autogen.c @@ -11,6 +11,11 @@ #include +/* DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS - do */ +static const struct nla_policy dev_energymodel_get_perf_domains_nl_policy[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID + 1] = { + [DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID] = { .type = NLA_U32, }, +}; + /* DEV_ENERGYMODEL_CMD_GET_PERF_TABLE - do */ static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID + 1] = { [DEV_ENERGYMODEL_A_PERF_TABLE_PERF_DOMAIN_ID] = { .type = NLA_U32, }, @@ -18,10 +23,17 @@ static const struct nla_policy dev_energymodel_get_perf_table_nl_policy[DEV_ENER /* Ops table for dev_energymodel */ static const struct genl_split_ops dev_energymodel_nl_ops[] = { + { + .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS, + .doit = dev_energymodel_nl_get_perf_domains_doit, + .policy = dev_energymodel_get_perf_domains_nl_policy, + .maxattr = DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID, + .flags = GENL_CMD_CAP_DO, + }, { .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_DOMAINS, - .doit = dev_energymodel_nl_get_perf_domains_doit, - .flags = GENL_CMD_CAP_DO, + .dumpit = dev_energymodel_nl_get_perf_domains_dumpit, + .flags = GENL_CMD_CAP_DUMP, }, { .cmd = DEV_ENERGYMODEL_CMD_GET_PERF_TABLE, diff --git a/kernel/power/em_netlink_autogen.h b/kernel/power/em_netlink_autogen.h index f7e4bddcbd53..5caf2f7e18a5 100644 --- a/kernel/power/em_netlink_autogen.h +++ b/kernel/power/em_netlink_autogen.h @@ -14,6 +14,8 @@ int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, struct genl_info *info); +int dev_energymodel_nl_get_perf_domains_dumpit(struct sk_buff *skb, + struct netlink_callback *cb); int dev_energymodel_nl_get_perf_table_doit(struct sk_buff *skb, struct genl_info *info); From 49d106347913201b6bc6d810c964b90781db8343 Mon Sep 17 00:00:00 2001 From: Alison Schofield Date: Fri, 9 Jan 2026 11:49:44 -0800 Subject: [PATCH 039/102] cxl/acpi: Restore HBIW check before dereferencing platform_data Commit 4fe516d2ad1a ("cxl/acpi: Make the XOR calculations available for testing") split xormap handling code to create a reusable helper function but inadvertently dropped the check of HBIW values before dereferencing cxlrd->platform_data. When HBIW is 1 or 3, no xormaps are needed and platform_data may be NULL, leading to a potential NULL pointer dereference. Affects platform configs using XOR Arithmetic with HBIWs of 1 or 3, when performing DPA->HPA address translation for CXL events. Those events would be any of poison ops, general media, or dram. Restore the early return check for HBIW values of 1 and 3 before dereferencing platform_data. Fixes: 4fe516d2ad1a ("cxl/acpi: Make the XOR calculations available for testing") Signed-off-by: Alison Schofield Reviewed-by: Dave Jiang Link: https://patch.msgid.link/20260109194946.431083-1-alison.schofield@intel.com Signed-off-by: Dave Jiang --- drivers/cxl/acpi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 77ac940e3013..49bba2b9a3c4 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -75,9 +75,16 @@ EXPORT_SYMBOL_FOR_MODULES(cxl_do_xormap_calc, "cxl_translate"); static u64 cxl_apply_xor_maps(struct cxl_root_decoder *cxlrd, u64 addr) { - struct cxl_cxims_data *cximsd = cxlrd->platform_data; + int hbiw = cxlrd->cxlsd.nr_targets; + struct cxl_cxims_data *cximsd; - return cxl_do_xormap_calc(cximsd, addr, cxlrd->cxlsd.nr_targets); + /* No xormaps for host bridge interleave ways of 1 or 3 */ + if (hbiw == 1 || hbiw == 3) + return addr; + + cximsd = cxlrd->platform_data; + + return cxl_do_xormap_calc(cximsd, addr, hbiw); } struct cxl_cxims_context { From ca22c566b89164f6e670af56ecc45f47ef3df819 Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Thu, 8 Jan 2026 10:22:10 -0700 Subject: [PATCH 040/102] block: zero non-PI portion of auto integrity buffer The auto-generated integrity buffer for writes needs to be fully initialized before being passed to the underlying block device, otherwise the uninitialized memory can be read back by userspace or anyone with physical access to the storage device. If protection information is generated, that portion of the integrity buffer is already initialized. The integrity data is also zeroed if PI generation is disabled via sysfs or the PI tuple size is 0. However, this misses the case where PI is generated and the PI tuple size is nonzero, but the metadata size is larger than the PI tuple. In this case, the remainder ("opaque") of the metadata is left uninitialized. Generalize the BLK_INTEGRITY_CSUM_NONE check to cover any case when the metadata is larger than just the PI tuple. Signed-off-by: Caleb Sander Mateos Fixes: c546d6f43833 ("block: only zero non-PI metadata tuples in bio_integrity_prep") Reviewed-by: Anuj Gupta Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Signed-off-by: Jens Axboe --- block/bio-integrity-auto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c index 9850c338548d..cff025b06be1 100644 --- a/block/bio-integrity-auto.c +++ b/block/bio-integrity-auto.c @@ -140,7 +140,7 @@ bool bio_integrity_prep(struct bio *bio) return true; set_flags = false; gfp |= __GFP_ZERO; - } else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE) + } else if (bi->metadata_size > bi->pi_tuple_size) gfp |= __GFP_ZERO; break; default: From db8061bbb9b23534ecd69bccdfbd70f5c9543189 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Sat, 10 Jan 2026 23:12:11 +0200 Subject: [PATCH 041/102] drm/rockchip: dw_hdmi_qp: Switch to gpiod_set_value_cansleep() Since commit 20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping"), the Rockchip GPIO chip operations potentially sleep, hence the kernel complains when trying to make use of the non-sleeping API: [ 16.653343] WARNING: drivers/gpio/gpiolib.c:3902 at gpiod_set_value+0xd0/0x108, CPU#5: kworker/5:1/93 ... [ 16.678470] Hardware name: Radxa ROCK 5B (DT) [ 16.682374] Workqueue: events dw_hdmi_qp_rk3588_hpd_work [rockchipdrm] ... [ 16.729314] Call trace: [ 16.731846] gpiod_set_value+0xd0/0x108 (P) [ 16.734548] dw_hdmi_qp_rockchip_encoder_enable+0xbc/0x3a8 [rockchipdrm] [ 16.737487] drm_atomic_helper_commit_encoder_bridge_enable+0x314/0x380 [drm_kms_helper] [ 16.740555] drm_atomic_helper_commit_tail_rpm+0xa4/0x100 [drm_kms_helper] [ 16.743501] commit_tail+0x1e0/0x2c0 [drm_kms_helper] [ 16.746290] drm_atomic_helper_commit+0x274/0x2b8 [drm_kms_helper] [ 16.749178] drm_atomic_commit+0x1f0/0x248 [drm] [ 16.752000] drm_client_modeset_commit_atomic+0x490/0x5d0 [drm] [ 16.754954] drm_client_modeset_commit_locked+0xf4/0x400 [drm] [ 16.757911] drm_client_modeset_commit+0x50/0x80 [drm] [ 16.760791] __drm_fb_helper_restore_fbdev_mode_unlocked+0x9c/0x170 [drm_kms_helper] [ 16.763843] drm_fb_helper_hotplug_event+0x340/0x368 [drm_kms_helper] [ 16.766780] drm_fbdev_client_hotplug+0x64/0x1d0 [drm_client_lib] [ 16.769634] drm_client_hotplug+0x178/0x240 [drm] [ 16.772455] drm_client_dev_hotplug+0x170/0x1c0 [drm] [ 16.775303] drm_connector_helper_hpd_irq_event+0xa4/0x178 [drm_kms_helper] [ 16.778248] dw_hdmi_qp_rk3588_hpd_work+0x44/0xb8 [rockchipdrm] [ 16.781080] process_one_work+0xc3c/0x1658 [ 16.783719] worker_thread+0xa24/0xc40 [ 16.786333] kthread+0x3b4/0x3d8 [ 16.788889] ret_from_fork+0x10/0x20 Since gpiod_get_value() is called from a context that can sleep, switch to its *_cansleep() variant and get rid of the issue. Signed-off-by: Cristian Ciocaltea Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20260110-dw-hdmi-qp-cansleep-v1-1-1ce937c5b201@collabora.com --- drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 6e39e8a00774..8604342f9943 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -121,7 +121,7 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) struct drm_crtc *crtc = encoder->crtc; /* Unconditionally switch to TMDS as FRL is not yet supported */ - gpiod_set_value(hdmi->frl_enable_gpio, 0); + gpiod_set_value_cansleep(hdmi->frl_enable_gpio, 0); if (!crtc || !crtc->state) return; From c18790018799155e58d5a11c6697f9c398bf8b60 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 9 Jan 2026 14:08:32 +0100 Subject: [PATCH 042/102] gpio: davinci: implement .get_direction() It's strongly recommended for GPIO drivers to always implement the .get_direction() callback - even for fixed-direction controllers. GPIO core will even emit a warning if the callback is missing, when users try to read the direction of a pin. Implement .get_direction() for gpio-davinci. Reported-by: Michael Walle Closes: https://lore.kernel.org/all/DFJAFK3DTBOZ.3G2P3A5IH34GF@kernel.org/ Reviewed-by: Linus Walleij Fixes: a060b8c511ab ("gpiolib: implement low-level, shared GPIO support") Tested-by: Michael Walle # on sa67 Link: https://lore.kernel.org/r/20260109130832.27326-1-bartosz.golaszewski@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-davinci.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 538f27209ce7..97780f27ce5b 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -6,6 +6,7 @@ * Copyright (c) 2007, MontaVista Software, Inc. */ +#include #include #include #include @@ -109,6 +110,22 @@ davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value) return __davinci_direction(chip, offset, true, value); } +static int davinci_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct davinci_gpio_controller *d = gpiochip_get_data(chip); + struct davinci_gpio_regs __iomem *g; + u32 mask = __gpio_mask(offset), val; + int bank = offset / 32; + + g = d->regs[bank]; + + guard(spinlock_irqsave)(&d->lock); + + val = readl_relaxed(&g->dir); + + return (val & mask) ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT; +} + /* * Read the pin's value (works even if it's set up as output); * returns zero/nonzero. @@ -203,6 +220,7 @@ static int davinci_gpio_probe(struct platform_device *pdev) chips->chip.get = davinci_gpio_get; chips->chip.direction_output = davinci_direction_out; chips->chip.set = davinci_gpio_set; + chips->chip.get_direction = davinci_get_direction; chips->chip.ngpio = ngpio; chips->chip.base = -1; From 471e998c0e31206ff0eac7202b2659698cf9b46e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 9 Jan 2026 11:55:56 +0100 Subject: [PATCH 043/102] gpiolib: remove redundant callback check The presence of the .get_direction() callback is already checked in gpiochip_get_direction(). Remove the duplicated check which also returns the wrong error code to user-space. Fixes: e623c4303ed1 ("gpiolib: sanitize the return value of gpio_chip::get_direction()") Reported-by: Michael Walle Closes: https://lore.kernel.org/all/DFJAFK3DTBOZ.3G2P3A5IH34GF@kernel.org/ Link: https://lore.kernel.org/r/20260109105557.20024-1-bartosz.golaszewski@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index dcf427d3cf43..fe2d107b0a84 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -468,9 +468,6 @@ int gpiod_get_direction(struct gpio_desc *desc) test_bit(GPIOD_FLAG_IS_OUT, &flags)) return 0; - if (!guard.gc->get_direction) - return -ENOTSUPP; - ret = gpiochip_get_direction(guard.gc, offset); if (ret < 0) return ret; From 81d0223832f99c0833e46be114a8310888015f8b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 8 Jan 2026 15:12:03 -0500 Subject: [PATCH 044/102] drm/i915/guc: make 'guc_hw_reg_state' static as it isn't exported The guc_hw_reg_state array is not exported, so make it static. Fixes the following sparse warning: drivers/gpu/drm/i915/i915_gpu_error.c:692:3: warning: symbol 'guc_hw_reg_state' was not declared. Should it be static? Fixes: ba391a102ec11 ("drm/i915/guc: Include the GuC registers in the error state") Signed-off-by: Ben Dooks Reviewed-by: Rodrigo Vivi Link: https://patch.msgid.link/20260108201202.59250-2-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi (cherry picked from commit 701c47493328a8173996e7590733be3493af572f) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 7582ef34bf3f..303d8d9b7775 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -686,7 +686,7 @@ static void err_print_guc_ctb(struct drm_i915_error_state_buf *m, } /* This list includes registers that are useful in debugging GuC hangs. */ -const struct { +static const struct { u32 start; u32 count; } guc_hw_reg_state[] = { From 101b982654ac0305ab286b54d46de79b5b982f3a Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 8 Jan 2026 15:53:05 -0600 Subject: [PATCH 045/102] ASoC: dt-bindings: realtek,rt5640: Add missing properties/node The RT5640 has an MCLK pin and several users already define a clocks entry. A 'port' node is also in use and a common node for codecs. Signed-off-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260108215307.1138515-1-robh@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/realtek,rt5640.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index 3f4f59287c1c..a0b8bf6cb110 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -47,6 +47,12 @@ properties: reg: maxItems: 1 + clocks: + maxItems: 1 + + clock-names: + const: mclk + interrupts: maxItems: 1 description: The CODEC's interrupt output. @@ -121,6 +127,9 @@ properties: - 2 # Scale current by 1.0 - 3 # Scale current by 1.5 + port: + $ref: /schemas/graph.yaml#/properties/port + required: - compatible - reg From f66e7da2a6b1ba055d47d7c97c9c855729f868ed Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 8 Jan 2026 15:53:06 -0600 Subject: [PATCH 046/102] ASoC: dt-bindings: realtek,rt5640: Allow 7 for realtek,jack-detect-source The driver accepts and uses a value of 7 for realtek,jack-detect-source. What exactly it means isn't clear though. Signed-off-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260108215307.1138515-2-robh@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/realtek,rt5640.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index a0b8bf6cb110..cd95d7189d34 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -104,6 +104,7 @@ properties: - 4 # Use GPIO2 for jack-detect - 5 # Use GPIO3 for jack-detect - 6 # Use GPIO4 for jack-detect + - 7 # HDA? realtek,jack-detect-not-inverted: description: From 70d95c5d2081faca7e849fa9c6665c9e0dae3923 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Thu, 8 Jan 2026 16:49:36 -0600 Subject: [PATCH 047/102] ASoC: dt-bindings: rockchip-spdif: Allow "port" node Add a "port" node entry for Rockchip S/PDIF binding. It's already in use and a common property for DAIs. Signed-off-by: Rob Herring (Arm) Link: https://patch.msgid.link/20260108224938.1320809-1-robh@kernel.org Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rockchip-spdif.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml index 32dea7392e8d..56c755c22945 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml @@ -70,6 +70,9 @@ properties: "#sound-dai-cells": const: 0 + port: + $ref: /schemas/graph.yaml#/properties/port + required: - compatible - reg From d4026a44626490dc4eca4dd2c4d0816338fa179b Mon Sep 17 00:00:00 2001 From: Li Ming Date: Mon, 12 Jan 2026 20:05:26 +0800 Subject: [PATCH 048/102] cxl/hdm: Fix potential infinite loop in __cxl_dpa_reserve() In __cxl_dpa_reserve(), it will check if the new resource range is included in one of paritions of the cxl memory device. cxlds->nr_paritions is used to represent how many partitions information the cxl memory device has. In the loop, if driver cannot find a partition including the new resource range, it will be an infinite loop. [ dj: Removed incorrect fixes tag ] Fixes: 991d98f17d31 ("cxl: Make cxl_dpa_alloc() DPA partition number agnostic") Signed-off-by: Li Ming Reviewed-by: Ira Weiny Reviewed-by: Dave Jiang Link: https://patch.msgid.link/20260112120526.530232-1-ming.li@zohomail.com Signed-off-by: Dave Jiang --- drivers/cxl/core/hdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index 1c5d2022c87a..a470099a69f1 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -403,7 +403,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled, * is not set. */ if (cxled->part < 0) - for (int i = 0; cxlds->nr_partitions; i++) + for (int i = 0; i < cxlds->nr_partitions; i++) if (resource_contains(&cxlds->part[i].res, res)) { cxled->part = i; break; From 05f66cf5e7a5fc7c7227541f8a4a476037999916 Mon Sep 17 00:00:00 2001 From: Boqun Feng Date: Fri, 26 Dec 2025 19:39:38 +0800 Subject: [PATCH 049/102] PCI: Provide pci_free_irq_vectors() stub 473b9f331718 ("rust: pci: fix build failure when CONFIG_PCI_MSI is disabled") fixed a build error by providing Rust helpers when CONFIG_PCI_MSI is not set. However the Rust helpers rely on pci_free_irq_vectors(), which is only available when CONFIG_PCI=y. When CONFIG_PCI is not set, there is already a stub for pci_alloc_irq_vectors(). Add a similar stub for pci_free_irq_vectors(). Fixes: 473b9f331718 ("rust: pci: fix build failure when CONFIG_PCI_MSI is disabled") Reported-by: FUJITA Tomonori Closes: https://lore.kernel.org/rust-for-linux/20251209014312.575940-1-fujita.tomonori@gmail.com/ Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202512220740.4Kexm4dW-lkp@intel.com/ Reported-by: Liang Jie Closes: https://lore.kernel.org/rust-for-linux/20251222034415.1384223-1-buaajxlj@163.com/ Signed-off-by: Boqun Feng Signed-off-by: Bjorn Helgaas Reviewed-by: Drew Fustini Reviewed-by: David Gow Reviewed-by: Joel Fernandes Reviewed-by: Danilo Krummrich Link: https://patch.msgid.link/20251226113938.52145-1-boqun.feng@gmail.com --- include/linux/pci.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index 864775651c6f..b5cc0c2b9906 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2210,6 +2210,10 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, { return -ENOSPC; } + +static inline void pci_free_irq_vectors(struct pci_dev *dev) +{ +} #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ From 8f334e35220721f65180bc2e0fe9187436c2c475 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 7 Jan 2026 16:14:55 +0100 Subject: [PATCH 050/102] ACPI: PM: s2idle: Add missing checks to acpi_s2idle_begin_lps0() Commit 32ece31db4df ("ACPI: PM: s2idle: Only retrieve constraints when needed"), that attempted to avoid useless evaluation of LPS0 _DSM Function 1 in lps0_device_attach(), forgot to add checks for lps0_device_handle and sleep_no_lps0 to acpi_s2idle_begin_lps0() where they should be done before calling lpi_device_get_constraints() or lpi_device_get_constraints_amd(). Add the missing checks. Fixes: 32ece31db4df ("ACPI: PM: s2idle: Only retrieve constraints when needed") Signed-off-by: Rafael J. Wysocki Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/2818730.mvXUDI8C0e@rafael.j.wysocki --- drivers/acpi/x86/s2idle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 6d4d06236f61..2a9edb53d5d4 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -515,7 +515,8 @@ static struct acpi_scan_handler lps0_handler = { static int acpi_s2idle_begin_lps0(void) { - if (pm_debug_messages_on && !lpi_constraints_table) { + if (lps0_device_handle && !sleep_no_lps0 && pm_debug_messages_on && + !lpi_constraints_table) { if (acpi_s2idle_vendor_amd()) lpi_device_get_constraints_amd(); else From f34b32745e2c9f85ee33b42e7a8cdaa1ee1c16a3 Mon Sep 17 00:00:00 2001 From: sheetal Date: Wed, 17 Dec 2025 18:55:24 +0530 Subject: [PATCH 051/102] ASoC: tegra: Revert fix for uninitialized flat cache warning in tegra210_ahub Commit 4d4021b0bbd1 ("ASoC: tegra: Fix uninitialized flat cache warning in tegra210_ahub") attempted to fix the uninitialized flat cache warning that is observed for the Tegra210 AHUB driver. However, the change broke various audio tests because an -EBUSY error is returned when accessing registers from cache before they are read from hardware. Revert this change for now, until a proper fix is available. Fixes: 4d4021b0bbd1 ("ASoC: tegra: Fix uninitialized flat cache warning in tegra210_ahub") Signed-off-by: sheetal Acked-by: Jon Hunter Link: https://patch.msgid.link/20251217132524.2844499-1-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_ahub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index 261d9067d27b..e795907a3963 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -2077,7 +2077,7 @@ static const struct regmap_config tegra210_ahub_regmap_config = { .val_bits = 32, .reg_stride = 4, .max_register = TEGRA210_MAX_REGISTER_ADDR, - .cache_type = REGCACHE_FLAT_S, + .cache_type = REGCACHE_FLAT, }; static const struct regmap_config tegra186_ahub_regmap_config = { @@ -2085,7 +2085,7 @@ static const struct regmap_config tegra186_ahub_regmap_config = { .val_bits = 32, .reg_stride = 4, .max_register = TEGRA186_MAX_REGISTER_ADDR, - .cache_type = REGCACHE_FLAT_S, + .cache_type = REGCACHE_FLAT, }; static const struct regmap_config tegra264_ahub_regmap_config = { @@ -2094,7 +2094,7 @@ static const struct regmap_config tegra264_ahub_regmap_config = { .reg_stride = 4, .writeable_reg = tegra264_ahub_wr_reg, .max_register = TEGRA264_MAX_REGISTER_ADDR, - .cache_type = REGCACHE_FLAT_S, + .cache_type = REGCACHE_FLAT, }; static const struct tegra_ahub_soc_data soc_data_tegra210 = { From 6ab3d4353bf75005eaa375677c9fed31148154d6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 10 Jan 2026 16:27:28 +0100 Subject: [PATCH 052/102] drm/panel-simple: fix connector type for DataImage SCF0700C48GGU18 panel The connector type for the DataImage SCF0700C48GGU18 panel is missing and devm_drm_panel_bridge_add() requires connector type to be set. This leads to a warning and a backtrace in the kernel log and panel does not work: " WARNING: CPU: 3 PID: 38 at drivers/gpu/drm/bridge/panel.c:379 devm_drm_of_get_bridge+0xac/0xb8 " The warning is triggered by a check for valid connector type in devm_drm_panel_bridge_add(). If there is no valid connector type set for a panel, the warning is printed and panel is not added. Fill in the missing connector type to fix the warning and make the panel operational once again. Cc: stable@vger.kernel.org Fixes: 97ceb1fb08b6 ("drm/panel: simple: Add support for DataImage SCF0700C48GGU18") Signed-off-by: Marek Vasut Reviewed-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patch.msgid.link/20260110152750.73848-1-marex@nabladev.com --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b26b682826bc..246d6883fbf7 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1900,6 +1900,7 @@ static const struct panel_desc dataimage_scf0700c48ggu18 = { }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_DPI, }; static const struct display_timing dlc_dlc0700yzg_1_timing = { From 9380dc33cd6ae4a6857818fcefce31cf716f3fae Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 18 Dec 2025 14:34:43 +0100 Subject: [PATCH 053/102] drm/panel: simple: restore connector_type fallback The switch from devm_kzalloc() + drm_panel_init() to devm_drm_panel_alloc() introduced a regression. Several panel descriptors do not set connector_type. For those panels, panel_simple_probe() used to compute a connector type (currently DPI as a fallback) and pass that value to drm_panel_init(). After the conversion to devm_drm_panel_alloc(), the call unconditionally used desc->connector_type instead, ignoring the computed fallback and potentially passing DRM_MODE_CONNECTOR_Unknown, which drm_panel_bridge_add() does not allow. Move the connector_type validation / fallback logic before the devm_drm_panel_alloc() call and pass the computed connector_type to devm_drm_panel_alloc(), so panels without an explicit connector_type once again get the DPI default. Signed-off-by: Ludovic Desroches Fixes: de04bb0089a9 ("drm/panel/panel-simple: Use the new allocation in place of devm_kzalloc()") Cc: stable@vger.kernel.org Reviewed-by: Luca Ceresoli Link: https://lore.kernel.org/stable/20251126-lcd_panel_connector_type_fix-v2-1-c15835d1f7cb%40microchip.com Signed-off-by: Neil Armstrong Link: https://patch.msgid.link/20251218-lcd_panel_connector_type_fix-v3-1-ddcea6d8d7ef@microchip.com --- drivers/gpu/drm/panel/panel-simple.c | 109 +++++++++++++-------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 246d6883fbf7..162cc58c7b8f 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -623,8 +623,61 @@ static struct panel_simple *panel_simple_probe(struct device *dev) if (IS_ERR(desc)) return ERR_CAST(desc); + connector_type = desc->connector_type; + /* Catch common mistakes for panels. */ + switch (connector_type) { + case 0: + dev_warn(dev, "Specify missing connector_type\n"); + connector_type = DRM_MODE_CONNECTOR_DPI; + break; + case DRM_MODE_CONNECTOR_LVDS: + WARN_ON(desc->bus_flags & + ~(DRM_BUS_FLAG_DE_LOW | + DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_DATA_MSB_TO_LSB | + DRM_BUS_FLAG_DATA_LSB_TO_MSB)); + WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG && + desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA); + WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && + desc->bpc != 6); + WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG || + desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) && + desc->bpc != 8); + break; + case DRM_MODE_CONNECTOR_eDP: + dev_warn(dev, "eDP panels moved to panel-edp\n"); + return ERR_PTR(-EINVAL); + case DRM_MODE_CONNECTOR_DSI: + if (desc->bpc != 6 && desc->bpc != 8) + dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); + break; + case DRM_MODE_CONNECTOR_DPI: + bus_flags = DRM_BUS_FLAG_DE_LOW | + DRM_BUS_FLAG_DE_HIGH | + DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE | + DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | + DRM_BUS_FLAG_DATA_MSB_TO_LSB | + DRM_BUS_FLAG_DATA_LSB_TO_MSB | + DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE | + DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE; + if (desc->bus_flags & ~bus_flags) + dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags); + if (!(desc->bus_flags & bus_flags)) + dev_warn(dev, "Specify missing bus_flags\n"); + if (desc->bus_format == 0) + dev_warn(dev, "Specify missing bus_format\n"); + if (desc->bpc != 6 && desc->bpc != 8) + dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); + break; + default: + dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type); + connector_type = DRM_MODE_CONNECTOR_DPI; + break; + } + panel = devm_drm_panel_alloc(dev, struct panel_simple, base, - &panel_simple_funcs, desc->connector_type); + &panel_simple_funcs, connector_type); if (IS_ERR(panel)) return ERR_CAST(panel); @@ -666,60 +719,6 @@ static struct panel_simple *panel_simple_probe(struct device *dev) goto free_ddc; } - connector_type = desc->connector_type; - /* Catch common mistakes for panels. */ - switch (connector_type) { - case 0: - dev_warn(dev, "Specify missing connector_type\n"); - connector_type = DRM_MODE_CONNECTOR_DPI; - break; - case DRM_MODE_CONNECTOR_LVDS: - WARN_ON(desc->bus_flags & - ~(DRM_BUS_FLAG_DE_LOW | - DRM_BUS_FLAG_DE_HIGH | - DRM_BUS_FLAG_DATA_MSB_TO_LSB | - DRM_BUS_FLAG_DATA_LSB_TO_MSB)); - WARN_ON(desc->bus_format != MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && - desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_SPWG && - desc->bus_format != MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA); - WARN_ON(desc->bus_format == MEDIA_BUS_FMT_RGB666_1X7X3_SPWG && - desc->bpc != 6); - WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG || - desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) && - desc->bpc != 8); - break; - case DRM_MODE_CONNECTOR_eDP: - dev_warn(dev, "eDP panels moved to panel-edp\n"); - err = -EINVAL; - goto free_ddc; - case DRM_MODE_CONNECTOR_DSI: - if (desc->bpc != 6 && desc->bpc != 8) - dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); - break; - case DRM_MODE_CONNECTOR_DPI: - bus_flags = DRM_BUS_FLAG_DE_LOW | - DRM_BUS_FLAG_DE_HIGH | - DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE | - DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE | - DRM_BUS_FLAG_DATA_MSB_TO_LSB | - DRM_BUS_FLAG_DATA_LSB_TO_MSB | - DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE | - DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE; - if (desc->bus_flags & ~bus_flags) - dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags); - if (!(desc->bus_flags & bus_flags)) - dev_warn(dev, "Specify missing bus_flags\n"); - if (desc->bus_format == 0) - dev_warn(dev, "Specify missing bus_format\n"); - if (desc->bpc != 6 && desc->bpc != 8) - dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc); - break; - default: - dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type); - connector_type = DRM_MODE_CONNECTOR_DPI; - break; - } - dev_set_drvdata(dev, panel); /* From 6b2d155366581705a848833a9b626bfea41d5a8d Mon Sep 17 00:00:00 2001 From: "Nirjhar Roy (IBM)" Date: Mon, 12 Jan 2026 15:35:23 +0530 Subject: [PATCH 054/102] xfs: Fix the return value of xfs_rtcopy_summary() xfs_rtcopy_summary() should return the appropriate error code instead of always returning 0. The caller of this function which is xfs_growfs_rt_bmblock() is already handling the error. Fixes: e94b53ff699c ("xfs: cache last bitmap block in realtime allocator") Signed-off-by: Nirjhar Roy (IBM) Reviewed-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Cc: stable@vger.kernel.org # v6.7 Signed-off-by: Carlos Maiolino --- fs/xfs/xfs_rtalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 167298ad88dd..202dcd2f4039 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -126,7 +126,7 @@ xfs_rtcopy_summary( error = 0; out: xfs_rtbuf_cache_relse(oargs); - return 0; + return error; } /* * Mark an extent specified by start and len allocated. From e0aea42a32984a6fd13410aed7afd3bd0caeb1c1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 9 Jan 2026 16:18:53 +0100 Subject: [PATCH 055/102] xfs: mark __xfs_rtgroup_extents static __xfs_rtgroup_extents is not used outside of xfs_rtgroup.c, so mark it static. Move it and xfs_rtgroup_extents up in the file to avoid forward declarations. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_rtgroup.c | 50 ++++++++++++++++++------------------- fs/xfs/libxfs/xfs_rtgroup.h | 2 -- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 9186c58e83d5..5a3d0dc6ae1b 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -48,6 +48,31 @@ xfs_rtgroup_min_block( return 0; } +/* Compute the number of rt extents in this realtime group. */ +static xfs_rtxnum_t +__xfs_rtgroup_extents( + struct xfs_mount *mp, + xfs_rgnumber_t rgno, + xfs_rgnumber_t rgcount, + xfs_rtbxlen_t rextents) +{ + ASSERT(rgno < rgcount); + if (rgno == rgcount - 1) + return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents); + + ASSERT(xfs_has_rtgroups(mp)); + return mp->m_sb.sb_rgextents; +} + +xfs_rtxnum_t +xfs_rtgroup_extents( + struct xfs_mount *mp, + xfs_rgnumber_t rgno) +{ + return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount, + mp->m_sb.sb_rextents); +} + /* Precompute this group's geometry */ void xfs_rtgroup_calc_geometry( @@ -136,31 +161,6 @@ out_unwind_new_rtgs: return error; } -/* Compute the number of rt extents in this realtime group. */ -xfs_rtxnum_t -__xfs_rtgroup_extents( - struct xfs_mount *mp, - xfs_rgnumber_t rgno, - xfs_rgnumber_t rgcount, - xfs_rtbxlen_t rextents) -{ - ASSERT(rgno < rgcount); - if (rgno == rgcount - 1) - return rextents - ((xfs_rtxnum_t)rgno * mp->m_sb.sb_rgextents); - - ASSERT(xfs_has_rtgroups(mp)); - return mp->m_sb.sb_rgextents; -} - -xfs_rtxnum_t -xfs_rtgroup_extents( - struct xfs_mount *mp, - xfs_rgnumber_t rgno) -{ - return __xfs_rtgroup_extents(mp, rgno, mp->m_sb.sb_rgcount, - mp->m_sb.sb_rextents); -} - /* * Update the rt extent count of the previous tail rtgroup if it changed during * recovery (i.e. recovery of a growfs). diff --git a/fs/xfs/libxfs/xfs_rtgroup.h b/fs/xfs/libxfs/xfs_rtgroup.h index 03f1e2493334..73cace4d25c7 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.h +++ b/fs/xfs/libxfs/xfs_rtgroup.h @@ -285,8 +285,6 @@ void xfs_free_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno, int xfs_initialize_rtgroups(struct xfs_mount *mp, xfs_rgnumber_t first_rgno, xfs_rgnumber_t end_rgno, xfs_rtbxlen_t rextents); -xfs_rtxnum_t __xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno, - xfs_rgnumber_t rgcount, xfs_rtbxlen_t rextents); xfs_rtxnum_t xfs_rtgroup_extents(struct xfs_mount *mp, xfs_rgnumber_t rgno); void xfs_rtgroup_calc_geometry(struct xfs_mount *mp, struct xfs_rtgroup *rtg, xfs_rgnumber_t rgno, xfs_rgnumber_t rgcount, From baed03efe223b1649320e835d7e0c03b3dde0b0c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 9 Jan 2026 16:18:54 +0100 Subject: [PATCH 056/102] xfs: fix an overly long line in xfs_rtgroup_calc_geometry Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_rtgroup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 5a3d0dc6ae1b..be16efaa6925 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -83,7 +83,8 @@ xfs_rtgroup_calc_geometry( xfs_rtbxlen_t rextents) { rtg->rtg_extents = __xfs_rtgroup_extents(mp, rgno, rgcount, rextents); - rtg_group(rtg)->xg_block_count = rtg->rtg_extents * mp->m_sb.sb_rextsize; + rtg_group(rtg)->xg_block_count = + rtg->rtg_extents * mp->m_sb.sb_rextsize; rtg_group(rtg)->xg_min_gbno = xfs_rtgroup_min_block(mp, rgno); } From df7ec7226fbe14d8654193933da81b2470cc5814 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 9 Jan 2026 16:18:21 +0100 Subject: [PATCH 057/102] xfs: improve the assert at the top of xfs_log_cover Move each condition into a separate assert so that we can see which on triggered. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- fs/xfs/xfs_log.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a311385b23d8..d4544ccafea5 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1180,9 +1180,11 @@ xfs_log_cover( int error = 0; bool need_covered; - ASSERT((xlog_cil_empty(mp->m_log) && xlog_iclogs_empty(mp->m_log) && - !xfs_ail_min_lsn(mp->m_log->l_ailp)) || - xlog_is_shutdown(mp->m_log)); + if (!xlog_is_shutdown(mp->m_log)) { + ASSERT(xlog_cil_empty(mp->m_log)); + ASSERT(xlog_iclogs_empty(mp->m_log)); + ASSERT(!xfs_ail_min_lsn(mp->m_log->l_ailp)); + } if (!xfs_log_writable(mp)) return 0; From a65fd81207669367504b6da7758e130ee23a7dfe Mon Sep 17 00:00:00 2001 From: "Nirjhar Roy (IBM)" Date: Mon, 12 Jan 2026 13:54:02 +0530 Subject: [PATCH 058/102] xfs: Fix xfs_grow_last_rtg() The last rtg should be able to grow when the size of the last is less than (and not equal to) sb_rgextents. xfs_growfs with realtime groups fails without this patch. The reason is that, xfs_growfs_rtg() tries to grow the last rt group even when the last rt group is at its maximal size i.e, sb_rgextents. It fails with the following messages: XFS (loop0): Internal error block >= mp->m_rsumblocks at line 253 of file fs/xfs/libxfs/xfs_rtbitmap.c. Caller xfs_rtsummary_read_buf+0x20/0x80 XFS (loop0): Corruption detected. Unmount and run xfs_repair XFS (loop0): Internal error xfs_trans_cancel at line 976 of file fs/xfs/xfs_trans.c. Caller xfs_growfs_rt_bmblock+0x402/0x450 XFS (loop0): Corruption of in-memory data (0x8) detected at xfs_trans_cancel+0x10a/0x1f0 (fs/xfs/xfs_trans.c:977). Shutting down filesystem. XFS (loop0): Please unmount the filesystem and rectify the problem(s) Signed-off-by: Nirjhar Roy (IBM) Reviewed-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- fs/xfs/xfs_rtalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 202dcd2f4039..a12ffed12391 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1326,7 +1326,7 @@ xfs_grow_last_rtg( return true; if (mp->m_sb.sb_rgcount == 0) return false; - return xfs_rtgroup_extents(mp, mp->m_sb.sb_rgcount - 1) <= + return xfs_rtgroup_extents(mp, mp->m_sb.sb_rgcount - 1) < mp->m_sb.sb_rgextents; } From c360004c0160dbe345870f59f24595519008926f Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Fri, 9 Jan 2026 12:49:05 -0500 Subject: [PATCH 059/102] xfs: set max_agbno to allow sparse alloc of last full inode chunk Sparse inode cluster allocation sets min/max agbno values to avoid allocating an inode cluster that might map to an invalid inode chunk. For example, we can't have an inode record mapped to agbno 0 or that extends past the end of a runt AG of misaligned size. The initial calculation of max_agbno is unnecessarily conservative, however. This has triggered a corner case allocation failure where a small runt AG (i.e. 2063 blocks) is mostly full save for an extent to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this case, which happens to be the offset of the last possible valid inode chunk in the AG. In practice, we should be able to allocate the 4-block cluster at agbno 2052 to map to the parent inode record at agbno 2048, but the max_agbno value precludes it. Note that this can result in filesystem shutdown via dirty trans cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because the tail AG selection by the allocator sets t_highest_agno on the transaction. If the inode allocator spins around and finds an inode chunk with free inodes in an earlier AG, the subsequent dir name creation path may still fail to allocate due to the AG restriction and cancel. To avoid this problem, update the max_agbno calculation to the agbno prior to the last chunk aligned agbno in the AG. This is not necessarily the last valid allocation target for a sparse chunk, but since inode chunks (i.e. records) are chunk aligned and sparse allocs are cluster sized/aligned, this allows the sb_spino_align alignment restriction to take over and round down the max effective agbno to within the last valid inode chunk in the AG. Note that even though the allocator improvements in the aforementioned commit seem to avoid this particular dirty trans cancel situation, the max_agbno logic improvement still applies as we should be able to allocate from an AG that has been appropriately selected. The more important target for this patch however are older/stable kernels prior to this allocator rework/improvement. Cc: stable@vger.kernel.org # v4.2 Fixes: 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure") Signed-off-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- fs/xfs/libxfs/xfs_ialloc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index d97295eaebe6..c19d6d713780 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -848,15 +848,16 @@ sparse_alloc: * invalid inode records, such as records that start at agbno 0 * or extend beyond the AG. * - * Set min agbno to the first aligned, non-zero agbno and max to - * the last aligned agbno that is at least one full chunk from - * the end of the AG. + * Set min agbno to the first chunk aligned, non-zero agbno and + * max to one less than the last chunk aligned agbno from the + * end of the AG. We subtract 1 from max so that the cluster + * allocation alignment takes over and allows allocation within + * the last full inode chunk in the AG. */ args.min_agbno = args.mp->m_sb.sb_inoalignmt; args.max_agbno = round_down(xfs_ag_block_count(args.mp, pag_agno(pag)), - args.mp->m_sb.sb_inoalignmt) - - igeo->ialloc_blks; + args.mp->m_sb.sb_inoalignmt) - 1; error = xfs_alloc_vextent_near_bno(&args, xfs_agbno_to_fsb(pag, From 8e29db1b08808f709231e6fd4c79dcdee5b17a17 Mon Sep 17 00:00:00 2001 From: Radhi Bajahaw Date: Mon, 12 Jan 2026 21:38:14 +0100 Subject: [PATCH 060/102] ASoC: amd: yc: Fix microphone on ASUS M6500RE Add DMI match for ASUSTeK COMPUTER INC. M6500RE to enable the internal microphone. Signed-off-by: Radhi Bajahaw Link: https://patch.msgid.link/20260112203814.155-1-bajahawradhi@gmail.com Signed-off-by: Mark Brown --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index bf4d9d336561..0294177acc66 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -416,6 +416,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "M6500RE"), + } + }, { .driver_data = &acp6x_card, .matches = { From cbd46cbc5470f9cb0bbeff70561a3dd3e0769fe1 Mon Sep 17 00:00:00 2001 From: Aleksandrs Vinarskis Date: Mon, 12 Jan 2026 01:06:37 +0100 Subject: [PATCH 061/102] ALSA: hda/realtek: Add quirk for Asus Zephyrus G14 2025 using CS35L56, fix speakers Just like GA403U, this GA403W needs to remap woofers to DAC1. Similarly to other Asus devices, headphones/headset MIC is not working, however the pin config alone is not enough to fix it. From Windows dump of GA403W: 0x12, 0x90a60140 # Correctly set by codec out of the box 0x13, 0x90a60550 0x14, 0x90170510 0x17, 0x90170120 # Correctly set by codec out of the box 0x19, 0x03a11050 # Set by ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC 0x1a, 0x411115F0 0x1b, 0x03a11c30 # Set by ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC 0x1d, 0x40663A45 # Correctly set by codec out of the box 0x21, 0x03211430 Even with all the values set, MIC of the jack is not detected. Until a complete solution is found, set ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC for GA403W which fixes audio volume control for woofers. No need to create new quirk with missing pin config just yet, since its not making the situation better. Signed-off-by: Aleksandrs Vinarskis Link: https://patch.msgid.link/20260112-asus-rog-audio-v1-1-513957b4704e@vinarskis.com Signed-off-by: Takashi Iwai --- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 61c7372e6307..dbbe8b498583 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -6817,6 +6817,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8f42, "HP ZBook 8 G2a 14W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8f57, "HP Trekker G7JC", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8f62, "HP ZBook 8 G2a 16W", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED), + SND_PCI_QUIRK(0x1043, 0x1024, "ASUS Zephyrus G14 2025", ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x1032, "ASUS VivoBook X513EA", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1034, "ASUS GU605C", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), From c5e96e54eca3876d4ce8857e2e22adbe9f44f4a2 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 13 Jan 2026 13:09:54 +0000 Subject: [PATCH 062/102] ALSA: hda/cirrus_scodec_test: Fix incorrect setup of gpiochip Set gpiochip parent to the struct device of the dummy GPIO driver so that the software node will be associated with the GPIO chip. The recent commit e5d527be7e698 ("gpio: swnode: don't use the swnode's name as the key for GPIO lookup") broke cirrus_scodec_test, because the software node no longer gets associated with the GPIO driver by name. Instead, setting struct gpio_chip.parent to the owning struct device will find the node using a normal fwnode lookup. Signed-off-by: Richard Fitzgerald Fixes: 2144833e7b414 ("ALSA: hda: cirrus_scodec: Add KUnit test") Link: https://patch.msgid.link/20260113130954.574670-1-rf@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/hda/codecs/side-codecs/cirrus_scodec_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c index 3cca750857b6..159ac80a9314 100644 --- a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c +++ b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c @@ -103,6 +103,7 @@ static int cirrus_scodec_test_gpio_probe(struct platform_device *pdev) /* GPIO core modifies our struct gpio_chip so use a copy */ gpio_priv->chip = cirrus_scodec_test_gpio_chip; + gpio_priv->chip.parent = &pdev->dev; ret = devm_gpiochip_add_data(&pdev->dev, &gpio_priv->chip, gpio_priv); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to add gpiochip\n"); From 6a0243c4020636482797acfd48d7d9b0ea2f2a20 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 13 Jan 2026 13:40:56 +0000 Subject: [PATCH 063/102] ALSA: hda/cirrus_scodec_test: Fix test suite name Change the test suite name string to "snd-hda-cirrus-scodec-test". It was incorrectly named "snd-hda-scodec-cs35l56-test", a leftover from when the code under test was actually in the cs35l56 driver. Signed-off-by: Richard Fitzgerald Fixes: 2144833e7b414 ("ALSA: hda: cirrus_scodec: Add KUnit test") Link: https://patch.msgid.link/20260113134056.619051-1-rf@opensource.cirrus.com Signed-off-by: Takashi Iwai --- sound/hda/codecs/side-codecs/cirrus_scodec_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c index 159ac80a9314..dc35932b6b22 100644 --- a/sound/hda/codecs/side-codecs/cirrus_scodec_test.c +++ b/sound/hda/codecs/side-codecs/cirrus_scodec_test.c @@ -320,7 +320,7 @@ static struct kunit_case cirrus_scodec_test_cases[] = { }; static struct kunit_suite cirrus_scodec_test_suite = { - .name = "snd-hda-scodec-cs35l56-test", + .name = "snd-hda-cirrus-scodec-test", .init = cirrus_scodec_test_case_init, .test_cases = cirrus_scodec_test_cases, }; From dc2d5ddb193e363187bae2ad358245642d2721fb Mon Sep 17 00:00:00 2001 From: Shenghao Yang Date: Wed, 31 Dec 2025 13:50:26 +0800 Subject: [PATCH 064/102] drm/gud: fix NULL fb and crtc dereferences on USB disconnect On disconnect drm_atomic_helper_disable_all() is called which sets both the fb and crtc for a plane to NULL before invoking a commit. This causes a kernel oops on every display disconnect. Add guards for those dereferences. Cc: # 6.18.x Fixes: 73cfd166e045 ("drm/gud: Replace simple display pipe with DRM atomic helpers") Signed-off-by: Shenghao Yang Reviewed-by: Ruben Wauters Signed-off-by: Ruben Wauters Link: https://patch.msgid.link/20251231055039.44266-1-me@shenghaoyang.info --- drivers/gpu/drm/gud/gud_pipe.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 76d77a736d84..4b77be94348d 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -457,27 +457,20 @@ int gud_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct drm_crtc *crtc = new_plane_state->crtc; - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *crtc_state = NULL; const struct drm_display_mode *mode; struct drm_framebuffer *old_fb = old_plane_state->fb; struct drm_connector_state *connector_state = NULL; struct drm_framebuffer *fb = new_plane_state->fb; - const struct drm_format_info *format = fb->format; + const struct drm_format_info *format; struct drm_connector *connector; unsigned int i, num_properties; struct gud_state_req *req; int idx, ret; size_t len; - if (drm_WARN_ON_ONCE(plane->dev, !fb)) - return -EINVAL; - - if (drm_WARN_ON_ONCE(plane->dev, !crtc)) - return -EINVAL; - - crtc_state = drm_atomic_get_new_crtc_state(state, crtc); - - mode = &crtc_state->mode; + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, DRM_PLANE_NO_SCALING, @@ -492,6 +485,9 @@ int gud_plane_atomic_check(struct drm_plane *plane, if (old_plane_state->rotation != new_plane_state->rotation) crtc_state->mode_changed = true; + mode = &crtc_state->mode; + format = fb->format; + if (old_fb && old_fb->format != format) crtc_state->mode_changed = true; @@ -598,7 +594,7 @@ void gud_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_helper_damage_iter iter; int ret, idx; - if (crtc->state->mode_changed || !crtc->state->enable) { + if (!crtc || crtc->state->mode_changed || !crtc->state->enable) { cancel_work_sync(&gdrm->work); mutex_lock(&gdrm->damage_lock); if (gdrm->fb) { From ef5749ef8b307bf8717945701b1b79d036af0a15 Mon Sep 17 00:00:00 2001 From: Edward Adam Davis Date: Tue, 13 Jan 2026 16:29:23 +0800 Subject: [PATCH 065/102] ALSA: usb-audio: Prevent excessive number of frames In this case, the user constructed the parameters with maxpacksize 40 for rate 22050 / pps 1000, and packsize[0] 22 packsize[1] 23. The buffer size for each data URB is maxpacksize * packets, which in this example is 40 * 6 = 240; When the user performs a write operation to send audio data into the ALSA PCM playback stream, the calculated number of frames is packsize[0] * packets = 264, which exceeds the allocated URB buffer size, triggering the out-of-bounds (OOB) issue reported by syzbot [1]. Added a check for the number of single data URB frames when calculating the number of frames to prevent [1]. [1] BUG: KASAN: slab-out-of-bounds in copy_to_urb+0x261/0x460 sound/usb/pcm.c:1487 Write of size 264 at addr ffff88804337e800 by task syz.0.17/5506 Call Trace: copy_to_urb+0x261/0x460 sound/usb/pcm.c:1487 prepare_playback_urb+0x953/0x13d0 sound/usb/pcm.c:1611 prepare_outbound_urb+0x377/0xc50 sound/usb/endpoint.c:333 Reported-by: syzbot+6db0415d6d5c635f72cb@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=6db0415d6d5c635f72cb Tested-by: syzbot+6db0415d6d5c635f72cb@syzkaller.appspotmail.com Signed-off-by: Edward Adam Davis Link: https://patch.msgid.link/tencent_9AECE6CD2C7A826D902D696C289724E8120A@qq.com Signed-off-by: Takashi Iwai --- sound/usb/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 54d01dfd820f..263abb36bb2d 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1553,7 +1553,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, for (i = 0; i < ctx->packets; i++) { counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, avail); - if (counts < 0) + if (counts < 0 || frames + counts >= ep->max_urb_frames) break; /* set up descriptor */ urb->iso_frame_desc[i].offset = frames * stride; From 40b94ec7edbbb867c4e26a1a43d2b898f04b93c5 Mon Sep 17 00:00:00 2001 From: Nilay Shroff Date: Tue, 13 Jan 2026 12:27:22 +0530 Subject: [PATCH 066/102] null_blk: fix kmemleak by releasing references to fault configfs items When CONFIG_BLK_DEV_NULL_BLK_FAULT_INJECTION is enabled, the null-blk driver sets up fault injection support by creating the timeout_inject, requeue_inject, and init_hctx_fault_inject configfs items as children of the top-level nullbX configfs group. However, when the nullbX device is removed, the references taken to these fault-config configfs items are not released. As a result, kmemleak reports a memory leak, for example: unreferenced object 0xc00000021ff25c40 (size 32): comm "mkdir", pid 10665, jiffies 4322121578 hex dump (first 32 bytes): 69 6e 69 74 5f 68 63 74 78 5f 66 61 75 6c 74 5f init_hctx_fault_ 69 6e 6a 65 63 74 00 88 00 00 00 00 00 00 00 00 inject.......... backtrace (crc 1a018c86): __kmalloc_node_track_caller_noprof+0x494/0xbd8 kvasprintf+0x74/0xf4 config_item_set_name+0xf0/0x104 config_group_init_type_name+0x48/0xfc fault_config_init+0x48/0xf0 0xc0080000180559e4 configfs_mkdir+0x304/0x814 vfs_mkdir+0x49c/0x604 do_mkdirat+0x314/0x3d0 sys_mkdir+0xa0/0xd8 system_call_exception+0x1b0/0x4f0 system_call_vectored_common+0x15c/0x2ec Fix this by explicitly releasing the references to the fault-config configfs items when dropping the reference to the top-level nullbX configfs group. Cc: stable@vger.kernel.org Reviewed-by: Chaitanya Kulkarni Fixes: bb4c19e030f4 ("block: null_blk: make fault-injection dynamically configurable per device") Signed-off-by: Nilay Shroff Signed-off-by: Jens Axboe --- drivers/block/null_blk/main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index c7c0fb79a6bf..4c0632ab4e1b 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -665,12 +665,22 @@ static void nullb_add_fault_config(struct nullb_device *dev) configfs_add_default_group(&dev->init_hctx_fault_config.group, &dev->group); } +static void nullb_del_fault_config(struct nullb_device *dev) +{ + config_item_put(&dev->init_hctx_fault_config.group.cg_item); + config_item_put(&dev->requeue_config.group.cg_item); + config_item_put(&dev->timeout_config.group.cg_item); +} + #else static void nullb_add_fault_config(struct nullb_device *dev) { } +static void nullb_del_fault_config(struct nullb_device *dev) +{ +} #endif static struct @@ -702,7 +712,7 @@ nullb_group_drop_item(struct config_group *group, struct config_item *item) null_del_dev(dev->nullb); mutex_unlock(&lock); } - + nullb_del_fault_config(dev); config_item_put(item); } From 2fa8961d3a6a1c2395d8d560ffed2c782681bade Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 18 Aug 2025 11:32:45 +0200 Subject: [PATCH 067/102] nvmet-tcp: fixup hang in nvmet_tcp_listen_data_ready() When the socket is closed while in TCP_LISTEN a callback is run to flush all outstanding packets, which in turns calls nvmet_tcp_listen_data_ready() with the sk_callback_lock held. So we need to check if we are in TCP_LISTEN before attempting to get the sk_callback_lock() to avoid a deadlock. Link: https://lore.kernel.org/linux-nvme/CAHj4cs-zu7eVB78yUpFjVe2UqMWFkLk8p+DaS3qj+uiGCXBAoA@mail.gmail.com/ Tested-by: Yi Zhang Reviewed-by: Sagi Grimberg Signed-off-by: Hannes Reinecke Signed-off-by: Keith Busch --- drivers/nvme/target/tcp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index d5966d007ba3..549a4786d1c3 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -2004,14 +2004,13 @@ static void nvmet_tcp_listen_data_ready(struct sock *sk) trace_sk_data_ready(sk); + if (sk->sk_state != TCP_LISTEN) + return; + read_lock_bh(&sk->sk_callback_lock); port = sk->sk_user_data; - if (!port) - goto out; - - if (sk->sk_state == TCP_LISTEN) + if (port) queue_work(nvmet_wq, &port->accept_work); -out: read_unlock_bh(&sk->sk_callback_lock); } From 8441c7d3bd6c5a52ab2ecf77e43a5bf262004f5c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 7 Jan 2026 13:05:43 +0100 Subject: [PATCH 068/102] cxl: Check for invalid addresses returned from translation functions on errors Translation functions may return an invalid address in case of errors. If the address is not checked the further use of the invalid value will cause an address corruption. Consistently check for a valid address returned by translation functions. Use RESOURCE_SIZE_MAX to indicate an invalid address for type resource_size_t. Depending on the type either RESOURCE_SIZE_MAX or ULLONG_MAX is used to indicate an address error. Propagating an invalid address from a failed translation may cause userspace to think it has received a valid SPA, when in fact it is wrong. The CXL userspace API, using trace events, expects ULLONG_MAX to indicate a translation failure. If ULLONG_MAX is not returned immediately, subsequent calculations can transform that bad address into a different value (!ULLONG_MAX), and an invalid SPA may be returned to userspace. This can lead to incorrect diagnostics and erroneous corrective actions. [ dj: Added user impact statement from Alison. ] [ dj: Fixed checkpatch tab alignment issue. ] Reviewed-by: Dave Jiang Signed-off-by: Robert Richter Fixes: c3dd67681c70 ("cxl/region: Add inject and clear poison by region offset") Fixes: b78b9e7b7979 ("cxl/region: Refactor address translation funcs for testing") Reviewed-by: Alison Schofield Reviewed-by: Jonathan Cameron Link: https://patch.msgid.link/20260107120544.410993-1-rrichter@amd.com Signed-off-by: Dave Jiang --- drivers/cxl/core/hdm.c | 2 +- drivers/cxl/core/region.c | 34 ++++++++++++++++++++------ tools/testing/cxl/test/cxl_translate.c | 26 ++++++++++++-------- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index a470099a69f1..eb5a3a7640c6 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -530,7 +530,7 @@ resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled) resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled) { - resource_size_t base = -1; + resource_size_t base = RESOURCE_SIZE_MAX; lockdep_assert_held(&cxl_rwsem.dpa); if (cxled->dpa_res) diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index fc36a5413d3f..5bd1213737fa 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -3118,7 +3118,7 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_region_params *p = &cxlr->params; struct cxl_endpoint_decoder *cxled = NULL; - u64 dpa_offset, hpa_offset, hpa; + u64 base, dpa_offset, hpa_offset, hpa; u16 eig = 0; u8 eiw = 0; int pos; @@ -3136,8 +3136,14 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, ways_to_eiw(p->interleave_ways, &eiw); granularity_to_eig(p->interleave_granularity, &eig); - dpa_offset = dpa - cxl_dpa_resource_start(cxled); + base = cxl_dpa_resource_start(cxled); + if (base == RESOURCE_SIZE_MAX) + return ULLONG_MAX; + + dpa_offset = dpa - base; hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, eiw, eig); + if (hpa_offset == ULLONG_MAX) + return ULLONG_MAX; /* Apply the hpa_offset to the region base address */ hpa = hpa_offset + p->res->start + p->cache_size; @@ -3146,6 +3152,9 @@ u64 cxl_dpa_to_hpa(struct cxl_region *cxlr, const struct cxl_memdev *cxlmd, if (cxlrd->ops.hpa_to_spa) hpa = cxlrd->ops.hpa_to_spa(cxlrd, hpa); + if (hpa == ULLONG_MAX) + return ULLONG_MAX; + if (!cxl_resource_contains_addr(p->res, hpa)) { dev_dbg(&cxlr->dev, "Addr trans fail: hpa 0x%llx not in region\n", hpa); @@ -3170,7 +3179,8 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset, struct cxl_region_params *p = &cxlr->params; struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_endpoint_decoder *cxled; - u64 hpa, hpa_offset, dpa_offset; + u64 hpa_offset = offset; + u64 dpa, dpa_offset; u16 eig = 0; u8 eiw = 0; int pos; @@ -3187,10 +3197,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset, * CXL HPA is assumed to equal SPA. */ if (cxlrd->ops.spa_to_hpa) { - hpa = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset); - hpa_offset = hpa - p->res->start; - } else { - hpa_offset = offset; + hpa_offset = cxlrd->ops.spa_to_hpa(cxlrd, p->res->start + offset); + if (hpa_offset == ULLONG_MAX) { + dev_dbg(&cxlr->dev, "HPA not found for %pr offset %#llx\n", + p->res, offset); + return -ENXIO; + } + hpa_offset -= p->res->start; } pos = cxl_calculate_position(hpa_offset, eiw, eig); @@ -3207,8 +3220,13 @@ static int region_offset_to_dpa_result(struct cxl_region *cxlr, u64 offset, cxled = p->targets[i]; if (cxled->pos != pos) continue; + + dpa = cxl_dpa_resource_start(cxled); + if (dpa != RESOURCE_SIZE_MAX) + dpa += dpa_offset; + result->cxlmd = cxled_to_memdev(cxled); - result->dpa = cxl_dpa_resource_start(cxled) + dpa_offset; + result->dpa = dpa; return 0; } diff --git a/tools/testing/cxl/test/cxl_translate.c b/tools/testing/cxl/test/cxl_translate.c index 2200ae21795c..16328b2112b2 100644 --- a/tools/testing/cxl/test/cxl_translate.c +++ b/tools/testing/cxl/test/cxl_translate.c @@ -68,6 +68,8 @@ static u64 to_hpa(u64 dpa_offset, int pos, u8 r_eiw, u16 r_eig, u8 hb_ways, /* Calculate base HPA offset from DPA and position */ hpa_offset = cxl_calculate_hpa_offset(dpa_offset, pos, r_eiw, r_eig); + if (hpa_offset == ULLONG_MAX) + return ULLONG_MAX; if (math == XOR_MATH) { cximsd->nr_maps = hbiw_to_nr_maps[hb_ways]; @@ -258,19 +260,23 @@ static int test_random_params(void) pos = get_random_u32() % ways; dpa = get_random_u64() >> 12; + reverse_dpa = ULLONG_MAX; + reverse_pos = -1; + hpa = cxl_calculate_hpa_offset(dpa, pos, eiw, eig); - reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig); - reverse_pos = cxl_calculate_position(hpa, eiw, eig); + if (hpa != ULLONG_MAX) { + reverse_dpa = cxl_calculate_dpa_offset(hpa, eiw, eig); + reverse_pos = cxl_calculate_position(hpa, eiw, eig); + if (reverse_dpa == dpa && reverse_pos == pos) + continue; + } - if (reverse_dpa != dpa || reverse_pos != pos) { - pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n", - i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, - eig); + pr_err("test random iter %d FAIL hpa=%llu, dpa=%llu reverse_dpa=%llu, pos=%d reverse_pos=%d eiw=%u eig=%u\n", + i, hpa, dpa, reverse_dpa, pos, reverse_pos, eiw, eig); - if (failures++ > 10) { - pr_err("test random too many failures, stop\n"); - break; - } + if (failures++ > 10) { + pr_err("test random too many failures, stop\n"); + break; } } pr_info("..... test random: PASS %d FAIL %d\n", i - failures, failures); From 84164acba33158208c2b0e8e5607bdd43edc0dd4 Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Sun, 21 Dec 2025 16:37:14 +0900 Subject: [PATCH 069/102] nvmet: do not copy beyond sybsysnqn string length Commit edd17206e363 ("nvmet: remove redundant subsysnqn field from ctrl") replaced ctrl->subsysnqn with ctrl->subsys->subsysnqn. This change works as expected because both point to strings with the same data. However, their memory allocation lengths differ. ctrl->subsysnqn had the fixed size defined as NVMF_NQN_FILED_LEN, while ctrl->subsys->subsysnqn has variable length determined by kstrndup(). Due to this difference, KASAN slab-out-of-bounds occurs at memcpy() in nvmet_passthru_override_id_ctrl() after the commit. The failure can be recreated by running the blktests test case nvme/033. To prevent such failures, replace memcpy() with strscpy(), which copies only the string length and avoids overruns. Fixes: edd17206e363 ("nvmet: remove redundant subsysnqn field from ctrl") Signed-off-by: Shin'ichiro Kawasaki Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Reviewed-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- drivers/nvme/target/passthru.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index 96648ec2fadb..67c423a8b052 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -150,7 +150,7 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) * code path with duplicate ctrl subsysnqn. In order to prevent that we * mask the passthru-ctrl subsysnqn with the target ctrl subsysnqn. */ - memcpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn)); + strscpy(id->subnqn, ctrl->subsys->subsysnqn, sizeof(id->subnqn)); /* use fabric id-ctrl values */ id->ioccsz = cpu_to_le32((sizeof(struct nvme_command) + From 7edf6f7ef5345e1b4202912ca98aaa7c73e1e82c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 13 Jan 2026 14:36:54 +0100 Subject: [PATCH 070/102] ACPI: PM: s2idle: Add module parameter for LPS0 constraints checking Commit 32ece31db4df ("ACPI: PM: s2idle: Only retrieve constraints when needed") attempted to avoid useless evaluation of LPS0 _DSM Function 1 in lps0_device_attach() because pm_debug_messages_on might never be set (and that is the case on production systems most of the time), but it turns out that LPS0 _DSM Function 1 is generally problematic on some platforms and causes suspend issues to occur when pm_debug_messages_on is set now. In Linux, LPS0 _DSM Function 1 is only useful for diagnostics and only in the cases when the system does not reach the deepest platform idle state during suspend-to-idle for some reason. If such diagnostics is not necessary, evaluating it is a loss of time, so using it along with the other pm_debug_messages_on diagnostics is questionable because the latter is expected to be suitable for collecting debug information even during production use of system suspend. For this reason, add a module parameter called check_lps0_constraints to control whether or not the list of LPS0 constraints will be checked in acpi_s2idle_prepare_late_lps0() and so whether or not to evaluate LPS0 _DSM Function 1 (once) in acpi_s2idle_begin_lps0(). Fixes: 32ece31db4df ("ACPI: PM: s2idle: Only retrieve constraints when needed") Signed-off-by: Rafael J. Wysocki Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/2827214.mvXUDI8C0e@rafael.j.wysocki --- drivers/acpi/x86/s2idle.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 2a9edb53d5d4..cc3c83e4cc23 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -28,6 +28,10 @@ static bool sleep_no_lps0 __read_mostly; module_param(sleep_no_lps0, bool, 0644); MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface"); +static bool check_lps0_constraints __read_mostly; +module_param(check_lps0_constraints, bool, 0644); +MODULE_PARM_DESC(check_lps0_constraints, "Check LPS0 device constraints"); + static const struct acpi_device_id lps0_device_ids[] = { {"PNP0D80", }, {"", }, @@ -515,7 +519,7 @@ static struct acpi_scan_handler lps0_handler = { static int acpi_s2idle_begin_lps0(void) { - if (lps0_device_handle && !sleep_no_lps0 && pm_debug_messages_on && + if (lps0_device_handle && !sleep_no_lps0 && check_lps0_constraints && !lpi_constraints_table) { if (acpi_s2idle_vendor_amd()) lpi_device_get_constraints_amd(); @@ -540,7 +544,7 @@ static int acpi_s2idle_prepare_late_lps0(void) if (!lps0_device_handle || sleep_no_lps0) return 0; - if (pm_debug_messages_on) + if (check_lps0_constraints) lpi_check_constraints(); /* Screen off */ From 9e9bc6be0fa0b6b6b73f4f831f3b77716d0a8d9e Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Fri, 19 Dec 2025 16:52:02 -0500 Subject: [PATCH 071/102] drm/nouveau/disp/nv50-: Set lock_core in curs507a_prepare For a while, I've been seeing a strange issue where some (usually not all) of the display DMA channels will suddenly hang, particularly when there is a visible cursor on the screen that is being frequently updated, and especially when said cursor happens to go between two screens. While this brings back lovely memories of fixing Intel Skylake bugs, I would quite like to fix it :). It turns out the problem that's happening here is that we're managing to reach nv50_head_flush_set() in our atomic commit path without actually holding nv50_disp->mutex. This means that cursor updates happening in parallel (along with any other atomic updates that need to use the core channel) will race with eachother, which eventually causes us to corrupt the pushbuffer - leading to a plethora of various GSP errors, usually: nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 00000218 00102680 00000004 00800003 nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 0000021c 00040509 00000004 00000001 nouveau 0000:c1:00.0: gsp: Xid:56 CMDre 00000000 00000000 00000000 00000001 00000001 The reason this is happening is because generally we check whether we need to set nv50_atom->lock_core at the end of nv50_head_atomic_check(). However, curs507a_prepare is called from the fb_prepare callback, which happens after the atomic check phase. As a result, this can lead to commits that both touch the core channel but also don't grab nv50_disp->mutex. So, fix this by making sure that we set nv50_atom->lock_core in cus507a_prepare(). Reviewed-by: Dave Airlie Signed-off-by: Lyude Paul Fixes: 1590700d94ac ("drm/nouveau/kms/nv50-: split each resource type into their own source files") Cc: # v4.18+ Link: https://patch.msgid.link/20251219215344.170852-2-lyude@redhat.com --- drivers/gpu/drm/nouveau/dispnv50/curs507a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index a95ee5dcc2e3..1a889139cb05 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -84,6 +84,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, asyh->curs.handle = handle; asyh->curs.offset = offset; asyh->set.curs = asyh->curs.visible; + nv50_atom(asyh->state.state)->lock_core = true; } } From 456c4f5ff0c886fd49daaa4dec13160df872bbc3 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Fri, 19 Dec 2025 16:52:03 -0500 Subject: [PATCH 072/102] drm/nouveau/kms/nv50-: Assert we hold nv50_disp->lock in nv50_head_flush_* Now that we've had one bug that occurred in nouveau as the result of nv50_head_flush_* being called without the appropriate locks, let's add some lockdep asserts to make sure this doesn't happen in the future. Reviewed-by: Dave Airlie Signed-off-by: Lyude Paul Link: https://patch.msgid.link/20251219215344.170852-3-lyude@redhat.com --- drivers/gpu/drm/nouveau/dispnv50/head.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 3dd742b4f823..e32ed1db6c56 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -43,6 +43,9 @@ nv50_head_flush_clr(struct nv50_head *head, union nv50_head_atom_mask clr = { .mask = asyh->clr.mask & ~(flush ? 0 : asyh->set.mask), }; + + lockdep_assert_held(&head->disp->mutex); + if (clr.crc) nv50_crc_atomic_clr(head); if (clr.olut) head->func->olut_clr(head); if (clr.core) head->func->core_clr(head); @@ -65,6 +68,8 @@ nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh) void nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) { + lockdep_assert_held(&head->disp->mutex); + if (asyh->set.view ) head->func->view (head, asyh); if (asyh->set.mode ) head->func->mode (head, asyh); if (asyh->set.core ) head->func->core_set(head, asyh); From b91a565ed14fcf900b4d95e86882b4b763860986 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 8 Jan 2026 15:19:46 +0100 Subject: [PATCH 073/102] drm/sysfb: Remove duplicate declarations Commit 6046b49bafff ("drm/sysfb: Share helpers for integer validation") and commit e8c086880b2b ("drm/sysfb: Share helpers for screen_info validation") added duplicate function declarations. Remove the latter ones. Signed-off-by: Thomas Zimmermann Fixes: e8c086880b2b ("drm/sysfb: Share helpers for screen_info validation") Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: dri-devel@lists.freedesktop.org Cc: # v6.16+ Reviewed-by: Javier Martinez Canillas Link: https://patch.msgid.link/20260108145058.56943-7-tzimmermann@suse.de --- drivers/gpu/drm/sysfb/drm_sysfb_helper.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h index da670d7eeb2e..de96bfe7562c 100644 --- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h +++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h @@ -54,15 +54,6 @@ const struct drm_format_info *drm_sysfb_get_format_si(struct drm_device *dev, const struct screen_info *si); #endif -/* - * Input parsing - */ - -int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name, - u64 value, u32 max); -int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name, - u64 value, u32 max); - /* * Display modes */ From 1ddbcb910a06f53fc2b14e1743c6ad4ccfd7107f Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 12 Jan 2026 14:07:56 +0000 Subject: [PATCH 074/102] soundwire: Add missing EXPORT for sdw_slave_type include/sdw_type.h provides the function is_sdw_slave() which requires sdw_slave_type. But sdw_slave_type was not exported. Signed-off-by: Richard Fitzgerald Acked-by: Vinod Koul Reviewed-by: Pierre-Louis Bossart Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20260112140758.215799-2-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/soundwire/slave.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index 3d4d00188c26..d933cebad52b 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -23,6 +23,7 @@ const struct device_type sdw_slave_type = { .release = sdw_slave_release, .uevent = sdw_slave_uevent, }; +EXPORT_SYMBOL_GPL(sdw_slave_type); int sdw_slave_add(struct sdw_bus *bus, struct sdw_slave_id *id, struct fwnode_handle *fwnode) From 5b027c74f3ee8979193c50d31187edfa31acc0db Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 12 Jan 2026 14:07:57 +0000 Subject: [PATCH 075/102] ASoC: sdw_utils: Call init callbacks on the correct codec DAI asoc_sdw_rtd_init() needs to call the rtd_init() callbacks for each codec in a dailink. It was finding the codecs by looking for the matching DAI name in codec_info_list[] but this isn't correct, because the DAI name isn't guaranteed to be unique. Parts using the same codec driver (so the same DAI names) might require different machine driver setup. Instead, get the struct sdw_slave and extract the SoundWire part ID. Use this to lookup the entry in codec_info_list[]. This is the same identity info that was used to find the entry when the machine driver created the dailink. Signed-off-by: Richard Fitzgerald Fixes: e377c9477317 ("ASoC: intel/sdw_utils: move soundwire codec_info_list structure") Reviewed-by: Pierre-Louis Bossart Reviewed-by: Charles Keepax Link: https://patch.msgid.link/20260112140758.215799-3-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/sdw_utils/soc_sdw_utils.c | 43 ++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c index bf382aa07e92..ccf149f949e8 100644 --- a/sound/soc/sdw_utils/soc_sdw_utils.c +++ b/sound/soc/sdw_utils/soc_sdw_utils.c @@ -841,6 +841,19 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr) } EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, "SND_SOC_SDW_UTILS"); +static struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_sdw_id(const struct sdw_slave_id *id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) + if (id->part_id == codec_info_list[i].part_id && + (!codec_info_list[i].version_id || + id->sdw_version == codec_info_list[i].version_id)) + return &codec_info_list[i]; + + return NULL; +} + struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id) { int i; @@ -873,22 +886,46 @@ struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, i } EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, "SND_SOC_SDW_UTILS"); +static int asoc_sdw_find_codec_info_dai_index(const struct asoc_sdw_codec_info *codec_info, + const char *dai_name) +{ + int i; + + for (i = 0; i < codec_info->dai_num; i++) { + if (!strcmp(codec_info->dais[i].dai_name, dai_name)) + return i; + } + + return -ENOENT; +} + int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); struct asoc_sdw_codec_info *codec_info; struct snd_soc_dai *dai; + struct sdw_slave *sdw_peripheral; const char *spk_components=""; int dai_index; int ret; int i; for_each_rtd_codec_dais(rtd, i, dai) { - codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index); + if (is_sdw_slave(dai->component->dev)) + sdw_peripheral = dev_to_sdw_dev(dai->component->dev); + else if (dai->component->dev->parent && is_sdw_slave(dai->component->dev->parent)) + sdw_peripheral = dev_to_sdw_dev(dai->component->dev->parent); + else + continue; + + codec_info = asoc_sdw_find_codec_info_sdw_id(&sdw_peripheral->id); if (!codec_info) return -EINVAL; + dai_index = asoc_sdw_find_codec_info_dai_index(codec_info, dai->name); + WARN_ON(dai_index < 0); + /* * A codec dai can be connected to different dai links for capture and playback, * but we only need to call the rtd_init function once. @@ -898,6 +935,10 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd) if (codec_info->dais[dai_index].rtd_init_done) continue; + dev_dbg(card->dev, "%#x/%s initializing for %s/%s\n", + codec_info->part_id, codec_info->dais[dai_index].dai_name, + dai->component->name, dai->name); + /* * Add card controls and dapm widgets for the first codec dai. * The controls and widgets will be used for all codec dais. From 390caeed0897fcac75f3c414dbdd85d593183d9c Mon Sep 17 00:00:00 2001 From: Cole Leavitt Date: Tue, 13 Jan 2026 19:55:18 -0700 Subject: [PATCH 076/102] ASoC: sdw_utils: cs42l43: Enable Headphone pin for LINEOUT jack type The CS42L43 codec's load detection can return different impedance values that map to either HEADPHONE or LINEOUT jack types. However, the soc_jack_pins array only maps SND_JACK_HEADPHONE to the "Headphone" DAPM pin, not SND_JACK_LINEOUT. When headphones are detected with an impedance that maps to LINEOUT (such as impedance value 0x2), the driver reports SND_JACK_LINEOUT. Since this doesn't match the jack pin mask, the "Headphone" DAPM pin is not activated, and no audio is routed to the headphone outputs. Fix by adding SND_JACK_LINEOUT to the Headphone pin mask, so that both headphone and line-out detection properly enable the headphone output path. This fixes no audio output on devices like the Lenovo ThinkPad P16 Gen 3 where headphones are detected with LINEOUT impedance. Fixes: d74bad3b7452 ("ASoC: intel: sof_sdw_cs42l43: Create separate jacks for hp and mic") Reviewed-by: Charles Keepax Signed-off-by: Cole Leavitt Link: https://patch.msgid.link/20260114025518.28519-1-cole@unwrap.rs Signed-off-by: Mark Brown --- sound/soc/sdw_utils/soc_sdw_cs42l43.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sdw_utils/soc_sdw_cs42l43.c b/sound/soc/sdw_utils/soc_sdw_cs42l43.c index 4c954501e500..2685ff4f0932 100644 --- a/sound/soc/sdw_utils/soc_sdw_cs42l43.c +++ b/sound/soc/sdw_utils/soc_sdw_cs42l43.c @@ -44,7 +44,7 @@ static const struct snd_soc_dapm_route cs42l43_dmic_map[] = { static struct snd_soc_jack_pin soc_jack_pins[] = { { .pin = "Headphone", - .mask = SND_JACK_HEADPHONE, + .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, }, { .pin = "Headset Mic", From 4130dc47ce8f60d289d91e2bdd18c4d863ca3237 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Tue, 13 Jan 2026 11:58:44 +0100 Subject: [PATCH 077/102] ASoC: tlv320adcx140: invert DRE_ENABLE Looking at section 8.6.1.1.69 in datasheets for both 5140 and 6140 (3140 doesn't support DRE). REG ADCX140_DSP_CFG1 BIT 3 field "DRE_AGC_SEL" it select either DRE or AGC. It states: * 0 = DRE * 1 = AGC The control is called "DRE_ENABLE" and for it to be true it has to be active low. This commit will invert the control so "DRE_ENABLE" is active low. Signed-off-by: Emil Svendsen Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-1-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 443cf59cb71a..75e1007012a4 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -338,7 +338,7 @@ static const struct snd_kcontrol_new adcx140_dapm_ch4_dre_en_switch = SOC_DAPM_SINGLE("Switch", ADCX140_CH4_CFG0, 0, 1, 0); static const struct snd_kcontrol_new adcx140_dapm_dre_en_switch = - SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 0); + SOC_DAPM_SINGLE("Switch", ADCX140_DSP_CFG1, 3, 1, 1); /* Output Mixer */ static const struct snd_kcontrol_new adcx140_output_mixer_controls[] = { From be7664c81d3129fc313ef62ff275fd3d33cfecd4 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Tue, 13 Jan 2026 11:58:45 +0100 Subject: [PATCH 078/102] ASoC: tlv320adcx140: fix null pointer The "snd_soc_component" in "adcx140_priv" was only used once but never set. It was only used for reaching "dev" which is already present in "adcx140_priv". Fixes: 4e82971f7b55 ("ASoC: tlv320adcx140: Add a new kcontrol") Signed-off-by: Emil Svendsen Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-2-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 75e1007012a4..3fb1b6251e6f 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -23,7 +23,6 @@ #include "tlv320adcx140.h" struct adcx140_priv { - struct snd_soc_component *component; struct regulator *supply_areg; struct gpio_desc *gpio_reset; struct regmap *regmap; @@ -699,7 +698,6 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state) { int pwr_ctrl = 0; int ret = 0; - struct snd_soc_component *component = adcx140->component; if (power_state) pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ; @@ -711,7 +709,7 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state) ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB, adcx140->phase_calib_on ? 0x00 : 0x40); if (ret) - dev_err(component->dev, "%s: register write error %d\n", + dev_err(adcx140->dev, "%s: register write error %d\n", __func__, ret); } From d89aad92cfd15edbd704746f44c98fe687f9366f Mon Sep 17 00:00:00 2001 From: Dimitrios Katsaros Date: Tue, 13 Jan 2026 11:58:46 +0100 Subject: [PATCH 079/102] ASoC: tlv320adcx140: Propagate error codes during probe When scanning for the reset pin, we could get an -EPROBE_DEFER. The driver would assume that no reset pin had been defined, which would mean that the chip would never be powered. Now we both respect any error we get from devm_gpiod_get_optional. We also now properly report the missing GPIO definition when 'gpio_reset' is NULL. Signed-off-by: Dimitrios Katsaros Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-3-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 3fb1b6251e6f..58a6dfa228cc 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -1154,6 +1154,9 @@ static int adcx140_i2c_probe(struct i2c_client *i2c) adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(adcx140->gpio_reset)) + return dev_err_probe(&i2c->dev, PTR_ERR(adcx140->gpio_reset), + "Failed to get Reset GPIO\n"); + if (!adcx140->gpio_reset) dev_info(&i2c->dev, "Reset GPIO not defined\n"); adcx140->supply_areg = devm_regulator_get_optional(adcx140->dev, From 46378ab9fcb796dca46b51e10646f636e2c661f9 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Tue, 13 Jan 2026 11:58:47 +0100 Subject: [PATCH 080/102] ASoC: tlv320adcx140: fix word length The word length is the physical width of the channel slots. So the hw_params would misconfigure when format width and physical width doesn't match. Like S24_LE which has data width of 24 bits but physical width of 32 bits. So if using asymmetric formats you will get a lot of noise. Fixes: 689c7655b50c5 ("ASoC: tlv320adcx140: Add the tlv320adcx140 codec driver family") Signed-off-by: Emil Svendsen Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-4-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320adcx140.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 58a6dfa228cc..fdf4a9add852 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -725,7 +725,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component); u8 data = 0; - switch (params_width(params)) { + switch (params_physical_width(params)) { case 16: data = ADCX140_16_BIT_WORD; break; @@ -740,7 +740,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream, break; default: dev_err(component->dev, "%s: Unsupported width %d\n", - __func__, params_width(params)); + __func__, params_physical_width(params)); return -EINVAL; } From 0edb475ac0a7d153318a24d4dca175a270a5cc4f Mon Sep 17 00:00:00 2001 From: Nilay Shroff Date: Wed, 14 Jan 2026 12:54:13 +0530 Subject: [PATCH 081/102] nvme: fix PCIe subsystem reset controller state transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”) disallows controller state transitions directly from RESETTING to LIVE. However, the NVMe PCIe subsystem reset path relies on this transition to recover the controller on PowerPC (PPC) systems. On PPC systems, issuing a subsystem reset causes a temporary loss of communication with the NVMe adapter. A subsequent PCIe MMIO read then triggers EEH recovery, which restores the PCIe link and brings the controller back online. For EEH recovery to proceed correctly, the controller must transition back to the LIVE state. Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”), the controller can no longer transition directly from RESETTING to LIVE. As a result, EEH recovery exits prematurely, leaving the controller stuck in the RESETTING state. Fix this by explicitly transitioning the controller state from RESETTING to CONNECTING and then to LIVE. This satisfies the updated state transition rules and allows the controller to be successfully recovered on PPC systems following a PCIe subsystem reset. Cc: stable@vger.kernel.org Fixes: d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state") Reviewed-by: Daniel Wagner Signed-off-by: Nilay Shroff Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 29e715d5b8f3..58f3097888a7 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1532,7 +1532,10 @@ static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) } writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); - nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); + + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) || + !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) + goto unlock; /* * Read controller status to flush the previous write and trigger a From da579f05ef0faada3559e7faddf761c75cdf85e1 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 14 Jan 2026 16:54:05 +0800 Subject: [PATCH 082/102] io_uring: move local task_work in exit cancel loop With IORING_SETUP_DEFER_TASKRUN, task work is queued to ctx->work_llist (local work) rather than the fallback list. During io_ring_exit_work(), io_move_task_work_from_local() was called once before the cancel loop, moving work from work_llist to fallback_llist. However, task work can be added to work_llist during the cancel loop itself. There are two cases: 1) io_kill_timeouts() is called from io_uring_try_cancel_requests() to cancel pending timeouts, and it adds task work via io_req_queue_tw_complete() for each cancelled timeout: 2) URING_CMD requests like ublk can be completed via io_uring_cmd_complete_in_task() from ublk_queue_rq() during canceling, given ublk request queue is only quiesced when canceling the 1st uring_cmd. Since io_allowed_defer_tw_run() returns false in io_ring_exit_work() (kworker != submitter_task), io_run_local_work() is never invoked, and the work_llist entries are never processed. This causes io_uring_try_cancel_requests() to loop indefinitely, resulting in 100% CPU usage in kworker threads. Fix this by moving io_move_task_work_from_local() inside the cancel loop, ensuring any work on work_llist is moved to fallback before each cancel attempt. Cc: stable@vger.kernel.org Fixes: c0e0d6ba25f1 ("io_uring: add IORING_SETUP_DEFER_TASKRUN") Signed-off-by: Ming Lei Signed-off-by: Jens Axboe --- io_uring/io_uring.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 87a87396e940..b7a077c11c21 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3003,12 +3003,12 @@ static __cold void io_ring_exit_work(struct work_struct *work) mutex_unlock(&ctx->uring_lock); } - if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) - io_move_task_work_from_local(ctx); - /* The SQPOLL thread never reaches this path */ - while (io_uring_try_cancel_requests(ctx, NULL, true, false)) + do { + if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) + io_move_task_work_from_local(ctx); cond_resched(); + } while (io_uring_try_cancel_requests(ctx, NULL, true, false)); if (ctx->sq_data) { struct io_sq_data *sqd = ctx->sq_data; From 292e5757b2229c0c6f1d059123a85f8a28f4464d Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Thu, 4 Dec 2025 12:13:05 -0500 Subject: [PATCH 083/102] drm/amdgpu: Fix gfx9 update PTE mtype flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix copy&paste error, that should have been an assignment instead of an or, otherwise MTYPE_UC 0x3 can not be updated to MTYPE_RW 0x1. Signed-off-by: Philip Yang Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit fc1366016abe4103c0f0fac882811aea961ef213) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 8ad7519f7b58..f1ee3921d970 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1235,16 +1235,16 @@ static void gmc_v9_0_get_vm_pte(struct amdgpu_device *adev, *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_NC); break; case AMDGPU_VM_MTYPE_WC: - *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC); + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_WC); break; case AMDGPU_VM_MTYPE_RW: - *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW); + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_RW); break; case AMDGPU_VM_MTYPE_CC: - *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC); + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_CC); break; case AMDGPU_VM_MTYPE_UC: - *flags |= AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC); + *flags = AMDGPU_PTE_MTYPE_VG10(*flags, MTYPE_UC); break; } From 9cb6278b44c38899961b36d303d7b18b38be2a6e Mon Sep 17 00:00:00 2001 From: Lu Yao Date: Tue, 6 Jan 2026 10:37:12 +0800 Subject: [PATCH 084/102] drm/amdgpu: fix drm panic null pointer when driver not support atomic When driver not support atomic, fb using plane->fb rather than plane->state->fb. Fixes: fe151ed7af54 ("drm/amdgpu: add generic display panic helper code") Signed-off-by: Lu Yao Signed-off-by: Alex Deucher (cherry picked from commit 2f2a72de673513247cd6fae14e53f6c40c5841ef) --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index b5d34797d606..52bc04452812 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -1880,7 +1880,12 @@ int amdgpu_display_get_scanout_buffer(struct drm_plane *plane, struct drm_scanout_buffer *sb) { struct amdgpu_bo *abo; - struct drm_framebuffer *fb = plane->state->fb; + struct drm_framebuffer *fb; + + if (drm_drv_uses_atomic_modeset(plane->dev)) + fb = plane->state->fb; + else + fb = plane->fb; if (!fb) return -EINVAL; From 28695ca09d326461f8078332aa01db516983e8a2 Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Wed, 7 Jan 2026 15:37:28 -0600 Subject: [PATCH 085/102] drm/amd: Clean up kfd node on surprise disconnect When an eGPU is unplugged the KFD topology should also be destroyed for that GPU. This never happens because the fini_sw callbacks never get to run. Run them manually before calling amdgpu_device_ip_fini_early() when a device has already been disconnected. This location is intentionally chosen to make sure that the kfd locking refcount doesn't get incremented unintentionally. Cc: kent.russell@amd.com Closes: https://community.frame.work/t/amd-egpu-on-linux/8691/33 Signed-off-by: Mario Limonciello (AMD) Reviewed-by: Kent Russell Signed-off-by: Alex Deucher (cherry picked from commit 6a23e7b4332c10f8b56c33a9c5431b52ecff9aab) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d5c44bd34d45..d2c3885de711 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5063,6 +5063,14 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_ttm_set_buffer_funcs_status(adev, false); + /* + * device went through surprise hotplug; we need to destroy topology + * before ip_fini_early to prevent kfd locking refcount issues by calling + * amdgpu_amdkfd_suspend() + */ + if (drm_dev_is_unplugged(adev_to_drm(adev))) + amdgpu_amdkfd_device_fini_sw(adev); + amdgpu_device_ip_fini_early(adev); amdgpu_irq_fini_hw(adev); From 9c8120015270d8a31c335c7137977749e5e8cd30 Mon Sep 17 00:00:00 2001 From: Peter Colberg Date: Mon, 22 Dec 2025 12:42:48 -0500 Subject: [PATCH 086/102] Revert duplicate "drm/amdgpu: disable peer-to-peer access for DCC-enabled GC12 VRAM surfaces" This reverts commit 22a36e660d014925114feb09a2680bb3c2d1e279 once, which was merged twice due to an incorrect backmerge resolution. Fixes: ce0478b02ed2 ("Merge tag 'v6.18-rc6' into drm-next") Signed-off-by: Peter Colberg Signed-off-by: Alex Deucher (cherry picked from commit 38a0f4cf8c6147fd10baa206ab349f8ff724e391) --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index e22cfa7c6d32..c1461317eb29 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -83,18 +83,6 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf, struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); int r; - /* - * Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+. - * Such buffers cannot be safely accessed over P2P due to device-local - * compression metadata. Fallback to system-memory path instead. - * Device supports GFX12 (GC 12.x or newer) - * BO was created with the AMDGPU_GEM_CREATE_GFX12_DCC flag - * - */ - if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0) && - bo->flags & AMDGPU_GEM_CREATE_GFX12_DCC) - attach->peer2peer = false; - /* * Disable peer-to-peer access for DCC-enabled VRAM surfaces on GFX12+. * Such buffers cannot be safely accessed over P2P due to device-local From 122b15cdbcc2eaccd7c1e630bb79ff4c268dd3f4 Mon Sep 17 00:00:00 2001 From: Xiaogang Chen Date: Thu, 8 Jan 2026 09:50:36 -0600 Subject: [PATCH 087/102] drm/amdgpu: Use correct address to setup gart page table for vram access Use dst input parameter to setup gart page table entries instead of using fixed location. Fixes: 237d623ae659 ("drm/amdgpu/gart: Add helper to bind VRAM pages (v2)") Signed-off-by: Xiaogang Chen Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit ca5d4db8db843be7ed35fc9334737490c2b58d32) --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index d2237ce9da70..1485f4789440 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -375,7 +375,7 @@ void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset, * @start_page: first page to map in the GART aperture * @num_pages: number of pages to be mapped * @flags: page table entry flags - * @dst: CPU address of the GART table + * @dst: valid CPU address of GART table, cannot be null * * Binds a BO that is allocated in VRAM to the GART page table * (all ASICs). @@ -396,7 +396,7 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa, return; for (i = 0; i < num_pages; ++i) { - amdgpu_gmc_set_pte_pde(adev, adev->gart.ptr, + amdgpu_gmc_set_pte_pde(adev, dst, start_page + i, pa + AMDGPU_GPU_PAGE_SIZE * i, flags); } From b6dff005fcf32dd072f6f2d08ca461394a21bd4f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 9 Jan 2026 08:54:55 -0500 Subject: [PATCH 088/102] drm/amdgpu: make sure userqs are enabled in userq IOCTLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These IOCTLs shouldn't be called when userqs are not enabled. Make sure they are enabled before executing the IOCTLs. Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit d967509651601cddce7ff2a9f09479f3636f684d) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 16 ++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 9a969175900e..58b26c78b642 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -885,12 +885,28 @@ static int amdgpu_userq_input_args_validate(struct drm_device *dev, return 0; } +bool amdgpu_userq_enabled(struct drm_device *dev) +{ + struct amdgpu_device *adev = drm_to_adev(dev); + int i; + + for (i = 0; i < AMDGPU_HW_IP_NUM; i++) { + if (adev->userq_funcs[i]) + return true; + } + + return false; +} + int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { union drm_amdgpu_userq *args = data; int r; + if (!amdgpu_userq_enabled(dev)) + return -ENOTSUPP; + if (amdgpu_userq_input_args_validate(dev, args, filp) < 0) return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h index c37444427a14..b48b3bc293fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h @@ -141,6 +141,7 @@ uint64_t amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, struct drm_file *filp); u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev); +bool amdgpu_userq_enabled(struct drm_device *dev); int amdgpu_userq_suspend(struct amdgpu_device *adev); int amdgpu_userq_resume(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index eba9fb359047..53d8707f9881 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -471,6 +471,9 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, struct drm_exec exec; u64 wptr; + if (!amdgpu_userq_enabled(dev)) + return -ENOTSUPP; + num_syncobj_handles = args->num_syncobj_handles; syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles), size_mul(sizeof(u32), num_syncobj_handles)); @@ -653,6 +656,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, int r, i, rentry, wentry, cnt; struct drm_exec exec; + if (!amdgpu_userq_enabled(dev)) + return -ENOTSUPP; + num_read_bo_handles = wait_info->num_bo_read_handles; bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles), size_mul(sizeof(u32), num_read_bo_handles)); From 80614c509810fc051312d1a7ccac8d0012d6b8d0 Mon Sep 17 00:00:00 2001 From: Haoxiang Li Date: Thu, 8 Jan 2026 15:18:22 +0800 Subject: [PATCH 089/102] drm/amdkfd: fix a memory leak in device_queue_manager_init() If dqm->ops.initialize() fails, add deallocate_hiq_sdma_mqd() to release the memory allocated by allocate_hiq_sdma_mqd(). Move deallocate_hiq_sdma_mqd() up to ensure proper function visibility at the point of use. Fixes: 11614c36bc8f ("drm/amdkfd: Allocate MQD trunk for HIQ and SDMA") Signed-off-by: Haoxiang Li Signed-off-by: Felix Kuehling Reviewed-by: Oak Zeng Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher (cherry picked from commit b7cccc8286bb9919a0952c812872da1dcfe9d390) Cc: stable@vger.kernel.org --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index d7a2e7178ea9..8af0929ca40a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -2919,6 +2919,14 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm) return retval; } +static void deallocate_hiq_sdma_mqd(struct kfd_node *dev, + struct kfd_mem_obj *mqd) +{ + WARN(!mqd, "No hiq sdma mqd trunk to free"); + + amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem); +} + struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) { struct device_queue_manager *dqm; @@ -3042,19 +3050,14 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) return dqm; } + if (!dev->kfd->shared_resources.enable_mes) + deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd); + out_free: kfree(dqm); return NULL; } -static void deallocate_hiq_sdma_mqd(struct kfd_node *dev, - struct kfd_mem_obj *mqd) -{ - WARN(!mqd, "No hiq sdma mqd trunk to free"); - - amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem); -} - void device_queue_manager_uninit(struct device_queue_manager *dqm) { dqm->ops.stop(dqm); From 0a1253ba5096f531eaaef40caa4c069da6ad48ae Mon Sep 17 00:00:00 2001 From: "Mario Limonciello (AMD)" Date: Sun, 14 Dec 2025 08:59:16 -0600 Subject: [PATCH 090/102] drm/amd/display: Show link name in PSR status message [Why] The PSR message was moved in commit 4321742c394e ("drm/amd/display: Move PSR support message into amdgpu_dm"). This message however shows for every single link without showing which link is which. This can send a confusing message to the user. [How] Add link name into the message. Fixes: 4321742c394e ("drm/amd/display: Move PSR support message into amdgpu_dm") Reviewed-by: Alex Hung Signed-off-by: Mario Limonciello (AMD) Signed-off-by: Matthew Stewart Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit 99f77f6229c0766b980ae05affcf9f742d97de6a) --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 740711ac1037..936c3bc3f2d6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5626,7 +5626,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (psr_feature_enabled) { amdgpu_dm_set_psr_caps(link); - drm_info(adev_to_drm(adev), "PSR support %d, DC PSR ver %d, sink PSR ver %d DPCD caps 0x%x su_y_granularity %d\n", + drm_info(adev_to_drm(adev), "%s: PSR support %d, DC PSR ver %d, sink PSR ver %d DPCD caps 0x%x su_y_granularity %d\n", + aconnector->base.name, link->psr_settings.psr_feature_enabled, link->psr_settings.psr_version, link->dpcd_caps.psr_info.psr_version, From fee50077656d8a58011f13bca48f743d1b6d6015 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 15 Dec 2025 14:08:30 -0600 Subject: [PATCH 091/102] drm/amd/display: Bump the HDMI clock to 340MHz [Why] DP-HDMI dongles can execeed bandwidth requirements on high resolution monitors. This can lead to pruning the high resolution modes. HDMI 1.3 bumped the clock to 340MHz, but display code never matched it. [How] Set default to (DVI) 165MHz. Once HDMI display is identified update to 340MHz. Reported-by: Dianne Skoll Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4780 Reviewed-by: Chris Park Signed-off-by: Mario Limonciello Signed-off-by: Matthew Stewart Tested-by: Dan Wheeler Signed-off-by: Alex Deucher (cherry picked from commit ac1e65d8ade46c09fb184579b81acadf36dcb91e) Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h | 2 +- drivers/gpu/drm/amd/display/dc/link/link_detection.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h index b015e80672ec..fcd3ab4b0045 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h @@ -41,7 +41,7 @@ /* kHZ*/ #define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000 /* kHZ*/ -#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000 +#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 340000 struct dp_hdmi_dongle_signature_data { int8_t id[15];/* "DP-HDMI ADAPTOR"*/ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index e1940b8e5bc3..7fa6bc97a919 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -336,7 +336,7 @@ static void query_dp_dual_mode_adaptor( /* Assume we have no valid DP passive dongle connected */ *dongle = DISPLAY_DONGLE_NONE; - sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK; + sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK; /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/ if (!i2c_read( @@ -392,6 +392,8 @@ static void query_dp_dual_mode_adaptor( } } + if (is_valid_hdmi_signature) + sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK; if (is_type2_dongle) { uint32_t max_tmds_clk = From 52d3d115e9cc975b90b1fc49abf6d36ad5e8847a Mon Sep 17 00:00:00 2001 From: Vivek Das Mohapatra Date: Mon, 12 Jan 2026 15:28:56 +0000 Subject: [PATCH 092/102] drm/amd/display: Initialise backlight level values from hw Internal backlight levels are initialised from ACPI but the values are sometimes out of sync with the levels in effect until there has been a read from hardware (eg triggered by reading from sysfs). This means that the first drm_commit can cause the levels to be set to a different value than the actual starting one, which results in a sudden change in brightness. This path shows the problem (when the values are out of sync): amdgpu_dm_atomic_commit_tail() -> amdgpu_dm_commit_streams() -> amdgpu_dm_backlight_set_level(..., dm->brightness[n]) This patch calls the backlight ops get_brightness explicitly at the end of backlight registration to make sure dm->brightness[n] is in sync with the actual hardware levels. Fixes: 2fe87f54abdc ("drm/amd/display: Set default brightness according to ACPI") Signed-off-by: Vivek Das Mohapatra Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Alex Deucher (cherry picked from commit 318b1c36d82a0cd2b06a4bb43272fa6f1bc8adc1) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 936c3bc3f2d6..fae88ce8327f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5266,6 +5266,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) struct amdgpu_dm_backlight_caps *caps; char bl_name[16]; int min, max; + int real_brightness; + int init_brightness; if (aconnector->bl_idx == -1) return; @@ -5290,6 +5292,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) } else props.brightness = props.max_brightness = MAX_BACKLIGHT_LEVEL; + init_brightness = props.brightness; + if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) { drm_info(drm, "Using custom brightness curve\n"); props.scale = BACKLIGHT_SCALE_NON_LINEAR; @@ -5308,8 +5312,20 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) { drm_err(drm, "DM: Backlight registration failed!\n"); dm->backlight_dev[aconnector->bl_idx] = NULL; - } else + } else { + /* + * dm->brightness[x] can be inconsistent just after startup until + * ops.get_brightness is called. + */ + real_brightness = + amdgpu_dm_backlight_ops.get_brightness(dm->backlight_dev[aconnector->bl_idx]); + + if (real_brightness != init_brightness) { + dm->actual_brightness[aconnector->bl_idx] = real_brightness; + dm->brightness[aconnector->bl_idx] = real_brightness; + } drm_dbg_driver(drm, "DM: Registered Backlight device: %s\n", bl_name); + } } static int initialize_plane(struct amdgpu_display_manager *dm, From 90dbc0bc2aa60021615969841fed06790c992bde Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Tue, 6 Jan 2026 14:42:40 +0800 Subject: [PATCH 093/102] drm/amd/pm: fix smu overdrive data type wrong issue on smu 14.0.2 resolving the issue of incorrect type definitions potentially causing calculation errors. Fixes: 54f7f3ca982a ("drm/amdgpu/swm14: Update power limit logic") Signed-off-by: Yang Wang Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher (cherry picked from commit e3a03d0ae16d6b56e893cce8e52b44140e1ed985) --- drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index 33c3cd2e1e24..d7642d388bc3 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -1702,8 +1702,9 @@ static int smu_v14_0_2_get_power_limit(struct smu_context *smu, table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; CustomSkuTable_t *skutable = &pptable->CustomSkuTable; - uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0; + int16_t od_percent_upper = 0, od_percent_lower = 0; uint32_t msg_limit = pptable->SkuTable.MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC]; + uint32_t power_limit; if (smu_v14_0_get_current_power_limit(smu, &power_limit)) power_limit = smu->adev->pm.ac_power ? From 0bea77b13b7649710108e6b67937ab4c7f8a9363 Mon Sep 17 00:00:00 2001 From: Prike Liang Date: Tue, 6 Jan 2026 17:00:57 +0800 Subject: [PATCH 094/102] drm/amdgpu: validate the flush_gpu_tlb_pasid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validate flush_gpu_tlb_pasid() availability before flushing tlb. Signed-off-by: Prike Liang Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit f4db9913e4d3dabe9ff3ea6178f2c1bc286012b8) --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 869bceb0fe2c..8924380086c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -732,6 +732,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, return 0; if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) { + + if (!adev->gmc.gmc_funcs->flush_gpu_tlb_pasid) + return 0; + if (adev->gmc.flush_tlb_needs_extra_type_2) adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid, 2, all_hub, From 808c2052f046d730a588f7b92b04a12f64970853 Mon Sep 17 00:00:00 2001 From: Prike Liang Date: Fri, 9 Jan 2026 16:15:11 +0800 Subject: [PATCH 095/102] Revert "drm/amdgpu: don't attach the tlb fence for SI" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 820b3d376e8a102c6aeab737ec6edebbbb710e04. It’s better to validate VM TLB flushes in the flush‑TLB backend rather than in the generic VM layer. Reverting this patch depends on commit fa7c231fc2b0 ("drm/amdgpu: validate the flush_gpu_tlb_pasid()") being present in the tree. Signed-off-by: Prike Liang Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit 9163fe4d790fb4e16d6b0e23f55b43cddd3d4a65) --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index c362d4dfb5bb..a67285118c37 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1069,9 +1069,7 @@ amdgpu_vm_tlb_flush(struct amdgpu_vm_update_params *params, } /* Prepare a TLB flush fence to be attached to PTs */ - if (!params->unlocked && - /* SI doesn't support pasid or KIQ/MES */ - params->adev->family > AMDGPU_FAMILY_SI) { + if (!params->unlocked) { amdgpu_vm_tlb_fence_create(params->adev, vm, fence); /* Makes sure no PD/PT is freed before the flush */ From 18dbcfb46f692e665c3fe3eee804e56c4eae53d6 Mon Sep 17 00:00:00 2001 From: Harish Kasiviswanathan Date: Sun, 11 Jan 2026 16:53:18 -0500 Subject: [PATCH 096/102] drm/amdkfd: No need to suspend whole MES to evict process Each queue of the process is individually removed and there is not need to suspend whole mes. Suspending mes stops kernel mode queues also causing unnecessary timeouts when running mixed work loads Fixes: 079ae5118e1f ("drm/amdkfd: fix suspend/resume all calls in mes based eviction path") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4765 Signed-off-by: Harish Kasiviswanathan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 3fd20580b96a6e9da65b94ac3b58ee288239b731) --- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 8af0929ca40a..625ea8ab7a74 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1209,14 +1209,8 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm, pr_debug_ratelimited("Evicting process pid %d queues\n", pdd->process->lead_thread->pid); - if (dqm->dev->kfd->shared_resources.enable_mes) { + if (dqm->dev->kfd->shared_resources.enable_mes) pdd->last_evict_timestamp = get_jiffies_64(); - retval = suspend_all_queues_mes(dqm); - if (retval) { - dev_err(dev, "Suspending all queues failed"); - goto out; - } - } /* Mark all queues as evicted. Deactivate all active queues on * the qpd. @@ -1246,10 +1240,6 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES : KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, USE_DEFAULT_GRACE_PERIOD); - } else { - retval = resume_all_queues_mes(dqm); - if (retval) - dev_err(dev, "Resuming all queues failed"); } out: From b2426a211dba6432e32a2e70e9183c6e134475c6 Mon Sep 17 00:00:00 2001 From: Srinivasan Shanmugam Date: Wed, 14 Jan 2026 16:14:53 +0530 Subject: [PATCH 097/102] drm/amdgpu/userq: Fix fence reference leak on queue teardown v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The user mode queue keeps a pointer to the most recent fence in userq->last_fence. This pointer holds an extra dma_fence reference. When the queue is destroyed, we free the fence driver and its xarray, but we forgot to drop the last_fence reference. Because of the missing dma_fence_put(), the last fence object can stay alive when the driver unloads. This leaves an allocated object in the amdgpu_userq_fence slab cache and triggers This is visible during driver unload as: BUG amdgpu_userq_fence: Objects remaining on __kmem_cache_shutdown() kmem_cache_destroy amdgpu_userq_fence: Slab cache still has objects Call Trace: kmem_cache_destroy amdgpu_userq_fence_slab_fini amdgpu_exit __do_sys_delete_module Fix this by putting userq->last_fence and clearing the pointer during amdgpu_userq_fence_driver_free(). This makes sure the fence reference is released and the slab cache is empty when the module exits. v2: Update to only release userq->last_fence with dma_fence_put() (Christian) Fixes: edc762a51c71 ("drm/amdgpu/userq: move some code around") Cc: Alex Deucher Cc: Christian König Signed-off-by: Srinivasan Shanmugam Reviewed-by: Christian König Signed-off-by: Alex Deucher (cherry picked from commit 8e051e38a8d45caf6a866d4ff842105b577953bb) --- drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 53d8707f9881..85e9edc1cb6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -141,6 +141,8 @@ static void amdgpu_userq_walk_and_drop_fence_drv(struct xarray *xa) void amdgpu_userq_fence_driver_free(struct amdgpu_usermode_queue *userq) { + dma_fence_put(userq->last_fence); + amdgpu_userq_walk_and_drop_fence_drv(&userq->fence_drv_xa); xa_destroy(&userq->fence_drv_xa); /* Drop the fence_drv reference held by user queue */ From d04f73668bebbc5a44a2771ea92b6ec253148050 Mon Sep 17 00:00:00 2001 From: Ivan Lipski Date: Tue, 13 Jan 2026 17:29:59 -0500 Subject: [PATCH 098/102] drm/amd/display: Add an hdmi_hpd_debounce_delay_ms module [Why&How] Right now, the HDMI HPD filter is enabled by default at 1500ms. We want to disable it by default, as most modern displays with HDMI do not require it for DPMS mode. The HPD can instead be enabled as a driver parameter with a custom delay value in ms (up to 5000ms). Fixes: c918e75e1ed9 ("drm/amd/display: Add an HPD filter for HDMI") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4859 Signed-off-by: Ivan Lipski Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Alex Deucher (cherry picked from commit 6a681cd9034587fe3550868bacfbd639d1c6891f) --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 11 +++++++++++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 ++++++++++++--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 5 ++++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 9f9774f58ce1..b20a06abb65d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -274,6 +274,8 @@ extern int amdgpu_rebar; extern int amdgpu_wbrf; extern int amdgpu_user_queue; +extern uint amdgpu_hdmi_hpd_debounce_delay_ms; + #define AMDGPU_VM_MAX_NUM_CTX 4096 #define AMDGPU_SG_THRESHOLD (256*1024*1024) #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 848e6b7db482..6ccb80e2d7c9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -247,6 +247,7 @@ int amdgpu_damage_clips = -1; /* auto */ int amdgpu_umsch_mm_fwlog; int amdgpu_rebar = -1; /* auto */ int amdgpu_user_queue = -1; +uint amdgpu_hdmi_hpd_debounce_delay_ms; DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0, "DRM_UT_CORE", @@ -1123,6 +1124,16 @@ module_param_named(rebar, amdgpu_rebar, int, 0444); MODULE_PARM_DESC(user_queue, "Enable user queues (-1 = auto (default), 0 = disable, 1 = enable, 2 = enable UQs and disable KQs)"); module_param_named(user_queue, amdgpu_user_queue, int, 0444); +/* + * DOC: hdmi_hpd_debounce_delay_ms (uint) + * HDMI HPD disconnect debounce delay in milliseconds. + * + * Used to filter short disconnect->reconnect HPD toggles some HDMI sinks + * generate while entering/leaving power save. Set to 0 to disable by default. + */ +MODULE_PARM_DESC(hdmi_hpd_debounce_delay_ms, "HDMI HPD disconnect debounce delay in milliseconds (0 to disable (by default), 1500 is common)"); +module_param_named(hdmi_hpd_debounce_delay_ms, amdgpu_hdmi_hpd_debounce_delay_ms, uint, 0644); + /* These devices are not supported by amdgpu. * They are supported by the mach64, r128, radeon drivers */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fae88ce8327f..1ea5a250440f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8947,9 +8947,18 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, mutex_init(&aconnector->hpd_lock); mutex_init(&aconnector->handle_mst_msg_ready); - aconnector->hdmi_hpd_debounce_delay_ms = AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS; - INIT_DELAYED_WORK(&aconnector->hdmi_hpd_debounce_work, hdmi_hpd_debounce_work); - aconnector->hdmi_prev_sink = NULL; + /* + * If HDMI HPD debounce delay is set, use the minimum between selected + * value and AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS + */ + if (amdgpu_hdmi_hpd_debounce_delay_ms) { + aconnector->hdmi_hpd_debounce_delay_ms = min(amdgpu_hdmi_hpd_debounce_delay_ms, + AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS); + INIT_DELAYED_WORK(&aconnector->hdmi_hpd_debounce_work, hdmi_hpd_debounce_work); + aconnector->hdmi_prev_sink = NULL; + } else { + aconnector->hdmi_hpd_debounce_delay_ms = 0; + } /* * configure support HPD hot plug connector_>polled default value is 0 diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index bd0403005f37..beb0d04d3e68 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -59,7 +59,10 @@ #define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL) -#define AMDGPU_DM_HDMI_HPD_DEBOUNCE_MS 1500 +/* + * Maximum HDMI HPD debounce delay in milliseconds + */ +#define AMDGPU_DM_MAX_HDMI_HPD_DEBOUNCE_MS 5000 /* #include "include/amdgpu_dal_power_if.h" #include "amdgpu_dm_irq.h" From ab2be3af8c4ea57f779474cd2a2fe8dd4ad537a6 Mon Sep 17 00:00:00 2001 From: Zhang Heng Date: Thu, 15 Jan 2026 09:58:44 +0800 Subject: [PATCH 099/102] ALSA: hda/realtek: Add quirk for HP Pavilion x360 to enable mute LED This quirk enables mute LED on HP Pavilion x360 2-in-1 Laptop 14-ek0xxx, which use ALC245 codec. Link: https://bugzilla.kernel.org/show_bug.cgi?id=220220 Cc: Signed-off-by: Zhang Heng Link: https://patch.msgid.link/20260115015844.3129890-1-zhangheng@kylinos.cn Signed-off-by: Takashi Iwai --- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index dbbe8b498583..29469e549791 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -6613,6 +6613,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8a4f, "HP Victus 15-fa0xxx (MB 8A4F)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4), SND_PCI_QUIRK(0x103c, 0x8a74, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), From be5a39e7994ec9f003c8569b670c794a4e5d1551 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 14 Jan 2026 22:08:35 +0000 Subject: [PATCH 100/102] ASoC: rt5640: Fix duplicate clock properties in DT binding Not quite overlapping changes to the rt5640 binding resulted in duplicate definitions of the clocks and clock-names properties. Delete one of them, preferring the simpler one. Reported-by: Jon Hunter Closes: https://lore.kernel.org/r/0e68c5f4-f68d-4544-bc7a-40694829db75@nvidia.com Signed-off-by: Mark Brown Link: https://patch.msgid.link/20260114-asoc-fix-rt5640-dt-clocks-v1-1-421d438673c2@kernel.org Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/realtek,rt5640.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml index 02591d6be12b..2eb631950963 100644 --- a/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml +++ b/Documentation/devicetree/bindings/sound/realtek,rt5640.yaml @@ -44,14 +44,6 @@ properties: - realtek,rt5640 - realtek,rt5639 - clocks: - items: - - description: phandle and clock specifier for codec MCLK. - - clock-names: - items: - - const: mclk - reg: maxItems: 1 From 46b8d0888f01f250fbd24d00ff80b755c3c42cd4 Mon Sep 17 00:00:00 2001 From: Shenghao Ding Date: Thu, 15 Jan 2026 20:49:06 +0800 Subject: [PATCH 101/102] ALSA: hda/tas2781: Add newly-released HP laptop HP released the new laptop with the subid 0x103C. Signed-off-by: Shenghao Ding Link: https://patch.msgid.link/20260115124907.629-1-shenghao-ding@ti.com Signed-off-by: Takashi Iwai --- sound/hda/codecs/side-codecs/tas2781_hda_i2c.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index 0e4bda3a544e..624a822341bb 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -2,7 +2,7 @@ // // TAS2781 HDA I2C driver // -// Copyright 2023 - 2025 Texas Instruments, Inc. +// Copyright 2023 - 2026 Texas Instruments, Inc. // // Author: Shenghao Ding // Current maintainer: Baojun Xu @@ -571,6 +571,9 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, case 0x1028: tas_hda->catlog_id = DELL; break; + case 0x103C: + tas_hda->catlog_id = HP; + break; default: tas_hda->catlog_id = LENOVO; break; From ec19ed2b3e2af8ec5380400cdee9cb6560144506 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Mon, 12 Jan 2026 15:19:28 -0800 Subject: [PATCH 102/102] rnbd-clt: fix refcount underflow in device unmap path During device unmapping (triggered by module unload or explicit unmap), a refcount underflow occurs causing a use-after-free warning: [14747.574913] ------------[ cut here ]------------ [14747.574916] refcount_t: underflow; use-after-free. [14747.574917] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x55/0x90, CPU#9: kworker/9:1/378 [14747.574924] Modules linked in: rnbd_client(-) rtrs_client rnbd_server rtrs_server rtrs_core ... [14747.574998] CPU: 9 UID: 0 PID: 378 Comm: kworker/9:1 Tainted: G O N 6.19.0-rc3lblk-fnext+ #42 PREEMPT(voluntary) [14747.575005] Workqueue: rnbd_clt_wq unmap_device_work [rnbd_client] [14747.575010] RIP: 0010:refcount_warn_saturate+0x55/0x90 [14747.575037] Call Trace: [14747.575038] [14747.575038] rnbd_clt_unmap_device+0x170/0x1d0 [rnbd_client] [14747.575044] process_one_work+0x211/0x600 [14747.575052] worker_thread+0x184/0x330 [14747.575055] ? __pfx_worker_thread+0x10/0x10 [14747.575058] kthread+0x10d/0x250 [14747.575062] ? __pfx_kthread+0x10/0x10 [14747.575066] ret_from_fork+0x319/0x390 [14747.575069] ? __pfx_kthread+0x10/0x10 [14747.575072] ret_from_fork_asm+0x1a/0x30 [14747.575083] [14747.575096] ---[ end trace 0000000000000000 ]--- Befor this patch :- The bug is a double kobject_put() on dev->kobj during device cleanup. Kobject Lifecycle: kobject_init_and_add() sets kobj.kref = 1 (initialization) kobject_put() sets kobj.kref = 0 (should be called once) * Before this patch: rnbd_clt_unmap_device() rnbd_destroy_sysfs() kobject_del(&dev->kobj) [remove from sysfs] kobject_put(&dev->kobj) PUT #1 (WRONG!) kref: 1 to 0 rnbd_dev_release() kfree(dev) [DEVICE FREED!] rnbd_destroy_gen_disk() [use-after-free!] rnbd_clt_put_dev() refcount_dec_and_test(&dev->refcount) kobject_put(&dev->kobj) PUT #2 (UNDERFLOW!) kref: 0 to -1 [WARNING!] The first kobject_put() in rnbd_destroy_sysfs() prematurely frees the device via rnbd_dev_release(), then the second kobject_put() in rnbd_clt_put_dev() causes refcount underflow. * After this patch :- Remove kobject_put() from rnbd_destroy_sysfs(). This function should only remove sysfs visibility (kobject_del), not manage object lifetime. Call Graph (FIXED): rnbd_clt_unmap_device() rnbd_destroy_sysfs() kobject_del(&dev->kobj) [remove from sysfs only] [kref unchanged: 1] rnbd_destroy_gen_disk() [device still valid] rnbd_clt_put_dev() refcount_dec_and_test(&dev->refcount) kobject_put(&dev->kobj) ONLY PUT (CORRECT!) kref: 1 to 0 [BALANCED] rnbd_dev_release() kfree(dev) [CLEAN DESTRUCTION] This follows the kernel pattern where sysfs removal (kobject_del) is separate from object destruction (kobject_put). Fixes: 581cf833cac4 ("block: rnbd: add .release to rnbd_dev_ktype") Signed-off-by: Chaitanya Kulkarni Acked-by: Jack Wang Reviewed-by: Jack Wang Signed-off-by: Jens Axboe --- drivers/block/rnbd/rnbd-clt.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index d1c354636315..8194a970f002 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -1662,7 +1662,6 @@ static void destroy_sysfs(struct rnbd_clt_dev *dev, /* To avoid deadlock firstly remove itself */ sysfs_remove_file_self(&dev->kobj, sysfs_self); kobject_del(&dev->kobj); - kobject_put(&dev->kobj); } }