diff --git a/1100-net-wwan-t7xx-add-delay-between-md-and-sap-suspend.patch b/1100-net-wwan-t7xx-add-delay-between-md-and-sap-suspend.patch new file mode 100644 index 000000000..7183b81a6 --- /dev/null +++ b/1100-net-wwan-t7xx-add-delay-between-md-and-sap-suspend.patch @@ -0,0 +1,73 @@ +From ce9a1d1e3fc747bc929f7560de3df369c1a45434 Mon Sep 17 00:00:00 2001 +From: Jose Ignacio Tornos Martinez +Date: Mon, 8 Jun 2026 17:25:54 +0200 +Subject: [PATCH] net: wwan: t7xx: Add delay between MD and SAP suspend + +JIRA: https://issues.redhat.com/browse/RHEL-155042 + +commit ae733795e593272f67d607c09d2a00637ac13ed0 +Author: Jose Ignacio Tornos Martinez +Date: Wed May 27 08:14:51 2026 +0200 + + net: wwan: t7xx: Add delay between MD and SAP suspend + + SAP (Service Access Point) suspend occasionally times out with error + -110 (ETIMEDOUT), followed by modem port errors and complete modem + failure requiring a system reboot to recover. + + Error symptoms: + mtk_t7xx 0000:72:00.0: [PM] SAP suspend error: -110 + mtk_t7xx 0000:72:00.0: can't suspend (...returned -110) + mtk_t7xx 0000:07:00.0: Failed to send skb: -22 + mtk_t7xx 0000:07:00.0: Write error on MBIM port, -22 + + The modem firmware needs time after receiving the MD (modem) suspend + request to complete internal operations before it is ready to accept + the SAP suspend request. Without this delay, if runtime PM attempts + to suspend while the firmware is busy, the SAP suspend command times + out, leaving the modem in an unrecoverable state. + + Root cause and userspace interaction: + ModemManager 1.24+ includes changes that reduce the likelihood of this + issue by ensuring the modem is in a low-power state before the kernel + attempts runtime suspend. However, the kernel driver should not depend + on specific userspace behavior or ModemManager versions. Older versions + (1.20-1.22) are still widely deployed, and the kernel should be robust + regardless of userspace implementation details. + + There appears to be no hardware status register or other mechanism + available to query whether the firmware is ready for SAP suspend. + A delay between the two suspend requests is the most reliable solution + found through testing. + + Add a 50ms delay between MD suspend and SAP suspend. This gives the + firmware adequate time to complete internal operations without adding + significant latency to the suspend path. This makes the driver robust + across all ModemManager versions and system conditions. + + Testing: 96+ hours of continuous operation with ModemManager 1.20.2 + and Fibocom FM350-GL modem. Zero SAP suspend timeouts observed across + 2000+ successful suspend/resume cycles. Previously failed within + 24 hours with 100% reproducibility. + + Signed-off-by: Jose Ignacio Tornos Martinez + Reviewed-by: Loic Poulain + Link: https://patch.msgid.link/20260527061451.12710-1-jtornosm@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Jose Ignacio Tornos Martinez + +diff --git a/drivers/net/wwan/t7xx/t7xx_pci.c b/drivers/net/wwan/t7xx/t7xx_pci.c +index eb137e0..46613bb 100644 +--- a/drivers/net/wwan/t7xx/t7xx_pci.c ++++ b/drivers/net/wwan/t7xx/t7xx_pci.c +@@ -447,6 +447,9 @@ static int __t7xx_pci_pm_suspend(struct pci_dev *pdev) + goto abort_suspend; + } + ++ /* Delay to prevent SAP suspend timeout */ ++ msleep(50); ++ + ret = t7xx_send_pm_request(t7xx_dev, H2D_CH_SUSPEND_REQ_AP); + if (ret) { + t7xx_send_pm_request(t7xx_dev, H2D_CH_RESUME_REQ); diff --git a/1101-timers-fix-null-function-pointer-race-in-timer-shutdown-sync.patch b/1101-timers-fix-null-function-pointer-race-in-timer-shutdown-sync.patch new file mode 100644 index 000000000..51f416cce --- /dev/null +++ b/1101-timers-fix-null-function-pointer-race-in-timer-shutdown-sync.patch @@ -0,0 +1,94 @@ +From 449e173e733a3f8bb9186785fc48265fbcfd8956 Mon Sep 17 00:00:00 2001 +From: Waiman Long +Date: Mon, 9 Mar 2026 23:09:28 -0400 +Subject: [PATCH] timers: Fix NULL function pointer race in + timer_shutdown_sync() + +JIRA: https://issues.redhat.com/browse/RHEL-152433 +CVE: CVE-2025-68214 + +commit 20739af07383e6eb1ec59dcd70b72ebfa9ac362c +Author: Yipeng Zou +Date: Sat, 22 Nov 2025 09:39:42 +0000 + + timers: Fix NULL function pointer race in timer_shutdown_sync() + + There is a race condition between timer_shutdown_sync() and timer + expiration that can lead to hitting a WARN_ON in expire_timers(). + + The issue occurs when timer_shutdown_sync() clears the timer function + to NULL while the timer is still running on another CPU. The race + scenario looks like this: + + CPU0 CPU1 + + lock_timer_base() + expire_timers() + base->running_timer = timer; + unlock_timer_base() + [call_timer_fn enter] + mod_timer() + ... + timer_shutdown_sync() + lock_timer_base() + // For now, will not detach the timer but only clear its function to NULL + if (base->running_timer != timer) + ret = detach_if_pending(timer, base, true); + if (shutdown) + timer->function = NULL; + unlock_timer_base() + [call_timer_fn exit] + lock_timer_base() + base->running_timer = NULL; + unlock_timer_base() + ... + // Now timer is pending while its function set to NULL. + // next timer trigger + + expire_timers() + WARN_ON_ONCE(!fn) // hit + ... + lock_timer_base() + // Now timer will detach + if (base->running_timer != timer) + ret = detach_if_pending(timer, base, true); + if (shutdown) + timer->function = NULL; + unlock_timer_base() + + The problem is that timer_shutdown_sync() clears the timer function + regardless of whether the timer is currently running. This can leave a + pending timer with a NULL function pointer, which triggers the + WARN_ON_ONCE(!fn) check in expire_timers(). + + Fix this by only clearing the timer function when actually detaching the + timer. If the timer is running, leave the function pointer intact, which is + safe because the timer will be properly detached when it finishes running. + + Fixes: 0cc04e80458a ("timers: Add shutdown mechanism to the internal functions") + Signed-off-by: Yipeng Zou + Signed-off-by: Thomas Gleixner + Cc: stable@vger.kernel.org + Link: https://patch.msgid.link/20251122093942.301559-1-zouyipeng@huawei.com + +Signed-off-by: Waiman Long + +diff --git a/kernel/time/timer.c b/kernel/time/timer.c +index 1391ea8..9b61f99 100644 +--- a/kernel/time/timer.c ++++ b/kernel/time/timer.c +@@ -1458,10 +1458,11 @@ static int __try_to_del_timer_sync(struct timer_list *timer, bool shutdown) + + base = lock_timer_base(timer, &flags); + +- if (base->running_timer != timer) ++ if (base->running_timer != timer) { + ret = detach_if_pending(timer, base, true); +- if (shutdown) +- timer->function = NULL; ++ if (shutdown) ++ timer->function = NULL; ++ } + + raw_spin_unlock_irqrestore(&base->lock, flags); + diff --git a/1102-procfs-avoid-fetching-build-id-while-holding-vma-lock.patch b/1102-procfs-avoid-fetching-build-id-while-holding-vma-lock.patch new file mode 100644 index 000000000..731569857 --- /dev/null +++ b/1102-procfs-avoid-fetching-build-id-while-holding-vma-lock.patch @@ -0,0 +1,274 @@ +From aac205646b22c60a35eeb810537df406a0ce2c65 Mon Sep 17 00:00:00 2001 +From: Rafael Aquini +Date: Wed, 1 Jul 2026 16:38:58 -0400 +Subject: [PATCH] procfs: avoid fetching build ID while holding VMA lock + +JIRA: https://redhat.atlassian.net/browse/RHEL-189666 +CVE: CVE-2026-23199 +Conflicts: + * fs/proc/task_mmu.c: minor differences in the hunks due to RHEL-10 yet not + utilizing granular per-VMA lock for PROCMAP_QUERY and instead relying on + the full-fledged mmap_lock semaphore for sinchronization. The convertion + of PROCMAP_QUERY to per-VMA locks is v6.18 material and its imposed churn + is not required nor it is a necessary condition for the correction of this + backport. + +commit b5cbacd7f86f4f62b8813688c8e73be94e8e1951 +Author: Andrii Nakryiko +Date: Thu Jan 29 13:53:40 2026 -0800 + + procfs: avoid fetching build ID while holding VMA lock + + Fix PROCMAP_QUERY to fetch optional build ID only after dropping mmap_lock + or per-VMA lock, whichever was used to lock VMA under question, to avoid + deadlock reported by syzbot: + + -> #1 (&mm->mmap_lock){++++}-{4:4}: + __might_fault+0xed/0x170 + _copy_to_iter+0x118/0x1720 + copy_page_to_iter+0x12d/0x1e0 + filemap_read+0x720/0x10a0 + blkdev_read_iter+0x2b5/0x4e0 + vfs_read+0x7f4/0xae0 + ksys_read+0x12a/0x250 + do_syscall_64+0xcb/0xf80 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + -> #0 (&sb->s_type->i_mutex_key#8){++++}-{4:4}: + __lock_acquire+0x1509/0x26d0 + lock_acquire+0x185/0x340 + down_read+0x98/0x490 + blkdev_read_iter+0x2a7/0x4e0 + __kernel_read+0x39a/0xa90 + freader_fetch+0x1d5/0xa80 + __build_id_parse.isra.0+0xea/0x6a0 + do_procmap_query+0xd75/0x1050 + procfs_procmap_ioctl+0x7a/0xb0 + __x64_sys_ioctl+0x18e/0x210 + do_syscall_64+0xcb/0xf80 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + rlock(&mm->mmap_lock); + lock(&sb->s_type->i_mutex_key#8); + lock(&mm->mmap_lock); + rlock(&sb->s_type->i_mutex_key#8); + + *** DEADLOCK *** + + This seems to be exacerbated (as we haven't seen these syzbot reports + before that) by the recent: + + 777a8560fd29 ("lib/buildid: use __kernel_read() for sleepable context") + + To make this safe, we need to grab file refcount while VMA is still locked, but + other than that everything is pretty straightforward. Internal build_id_parse() + API assumes VMA is passed, but it only needs the underlying file reference, so + just add another variant build_id_parse_file() that expects file passed + directly. + + [akpm@linux-foundation.org: fix up kerneldoc] + Link: https://lkml.kernel.org/r/20260129215340.3742283-1-andrii@kernel.org + Fixes: ed5d583a88a9 ("fs/procfs: implement efficient VMA querying API for /proc//maps") + Signed-off-by: Andrii Nakryiko + Reported-by: + Reviewed-by: Suren Baghdasaryan + Tested-by: Suren Baghdasaryan + Reviewed-by: Shakeel Butt + Cc: Alexei Starovoitov + Cc: Daniel Borkmann + Cc: Eduard Zingerman + Cc: Hao Luo + Cc: Jiri Olsa + Cc: John Fastabend + Cc: KP Singh + Cc: Martin KaFai Lau + Cc: Song Liu + Cc: Stanislav Fomichev + Cc: Yonghong Song + Cc: + Signed-off-by: Andrew Morton + +Signed-off-by: Rafael Aquini + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 4cb8583..27cc491 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -456,6 +456,7 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + struct procmap_query karg; + struct vm_area_struct *vma; + struct mm_struct *mm; ++ struct file *vm_file = NULL; + const char *name = NULL; + char build_id_buf[BUILD_ID_SIZE_MAX], *name_buf = NULL; + __u64 usize; +@@ -528,21 +529,6 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + karg.inode = 0; + } + +- if (karg.build_id_size) { +- __u32 build_id_sz; +- +- err = build_id_parse(vma, build_id_buf, &build_id_sz); +- if (err) { +- karg.build_id_size = 0; +- } else { +- if (karg.build_id_size < build_id_sz) { +- err = -ENAMETOOLONG; +- goto out; +- } +- karg.build_id_size = build_id_sz; +- } +- } +- + if (karg.vma_name_size) { + size_t name_buf_sz = min_t(size_t, PATH_MAX, karg.vma_name_size); + const struct path *path; +@@ -576,10 +562,34 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + karg.vma_name_size = name_sz; + } + ++ if (karg.build_id_size && vma->vm_file) ++ vm_file = get_file(vma->vm_file); ++ + /* unlock vma or mmap_lock, and put mm_struct before copying data to user */ + query_vma_teardown(mm, vma); + mmput(mm); + ++ if (karg.build_id_size) { ++ __u32 build_id_sz; ++ ++ if (vm_file) ++ err = build_id_parse_file(vm_file, build_id_buf, &build_id_sz); ++ else ++ err = -ENOENT; ++ if (err) { ++ karg.build_id_size = 0; ++ } else { ++ if (karg.build_id_size < build_id_sz) { ++ err = -ENAMETOOLONG; ++ goto out; ++ } ++ karg.build_id_size = build_id_sz; ++ } ++ } ++ ++ if (vm_file) ++ fput(vm_file); ++ + if (karg.vma_name_size && copy_to_user(u64_to_user_ptr(karg.vma_name_addr), + name, karg.vma_name_size)) { + kfree(name_buf); +@@ -599,6 +609,8 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + out: + query_vma_teardown(mm, vma); + mmput(mm); ++ if (vm_file) ++ fput(vm_file); + kfree(name_buf); + return err; + } +diff --git a/include/linux/buildid.h b/include/linux/buildid.h +index 831c1b4..7acc06b 100644 +--- a/include/linux/buildid.h ++++ b/include/linux/buildid.h +@@ -7,7 +7,10 @@ + #define BUILD_ID_SIZE_MAX 20 + + struct vm_area_struct; ++struct file; ++ + int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size); ++int build_id_parse_file(struct file *file, unsigned char *build_id, __u32 *size); + int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size); + int build_id_parse_buf(const void *buf, unsigned char *build_id, u32 buf_size); + +diff --git a/lib/buildid.c b/lib/buildid.c +index 8183310..c4b7376 100644 +--- a/lib/buildid.c ++++ b/lib/buildid.c +@@ -279,7 +279,7 @@ static int get_build_id_64(struct freader *r, unsigned char *build_id, __u32 *si + /* enough for Elf64_Ehdr, Elf64_Phdr, and all the smaller requests */ + #define MAX_FREADER_BUF_SZ 64 + +-static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, ++static int __build_id_parse(struct file *file, unsigned char *build_id, + __u32 *size, bool may_fault) + { + const Elf32_Ehdr *ehdr; +@@ -287,11 +287,7 @@ static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, + char buf[MAX_FREADER_BUF_SZ]; + int ret; + +- /* only works for page backed storage */ +- if (!vma->vm_file) +- return -EINVAL; +- +- freader_init_from_file(&r, buf, sizeof(buf), vma->vm_file, may_fault); ++ freader_init_from_file(&r, buf, sizeof(buf), file, may_fault); + + /* fetch first 18 bytes of ELF header for checks */ + ehdr = freader_fetch(&r, 0, offsetofend(Elf32_Ehdr, e_type)); +@@ -319,8 +315,8 @@ static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, + return ret; + } + +-/* +- * Parse build ID of ELF file mapped to vma ++/** ++ * build_id_parse_nofault() - Parse build ID of ELF file mapped to vma + * @vma: vma object + * @build_id: buffer to store build id, at least BUILD_ID_SIZE long + * @size: returns actual build id size in case of success +@@ -332,11 +328,14 @@ static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, + */ + int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size) + { +- return __build_id_parse(vma, build_id, size, false /* !may_fault */); ++ if (!vma->vm_file) ++ return -EINVAL; ++ ++ return __build_id_parse(vma->vm_file, build_id, size, false /* !may_fault */); + } + +-/* +- * Parse build ID of ELF file mapped to VMA ++/** ++ * build_id_parse() - Parse build ID of ELF file mapped to VMA + * @vma: vma object + * @build_id: buffer to store build id, at least BUILD_ID_SIZE long + * @size: returns actual build id size in case of success +@@ -348,7 +347,26 @@ int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, + */ + int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size) + { +- return __build_id_parse(vma, build_id, size, true /* may_fault */); ++ if (!vma->vm_file) ++ return -EINVAL; ++ ++ return __build_id_parse(vma->vm_file, build_id, size, true /* may_fault */); ++} ++ ++/** ++ * build_id_parse_file() - Parse build ID of ELF file ++ * @file: file object ++ * @build_id: buffer to store build id, at least BUILD_ID_SIZE long ++ * @size: returns actual build id size in case of success ++ * ++ * Assumes faultable context and can cause page faults to bring in file data ++ * into page cache. ++ * ++ * Return: 0 on success; negative error, otherwise ++ */ ++int build_id_parse_file(struct file *file, unsigned char *build_id, __u32 *size) ++{ ++ return __build_id_parse(file, build_id, size, true /* may_fault */); + } + + /** diff --git a/1103-procfs-fix-possible-double-mmput-in-do-procmap-query.patch b/1103-procfs-fix-possible-double-mmput-in-do-procmap-query.patch new file mode 100644 index 000000000..48fa6548e --- /dev/null +++ b/1103-procfs-fix-possible-double-mmput-in-do-procmap-query.patch @@ -0,0 +1,57 @@ +From a942817e22deae157ab3431184f3a760e616f696 Mon Sep 17 00:00:00 2001 +From: Rafael Aquini +Date: Wed, 1 Jul 2026 16:38:58 -0400 +Subject: [PATCH] procfs: fix possible double mmput() in do_procmap_query() + +JIRA: https://redhat.atlassian.net/browse/RHEL-189666 +CVE: CVE-2026-23199 + +commit 61dc9f776705d6db6847c101b98fa4f0e9eb6fa3 +Author: Andrii Nakryiko +Date: Tue Feb 10 11:27:38 2026 -0800 + + procfs: fix possible double mmput() in do_procmap_query() + + When user provides incorrectly sized buffer for build ID for PROCMAP_QUERY + we return with -ENAMETOOLONG error. After recent changes this condition + happens later, after we unlocked mmap_lock/per-VMA lock and did mmput(), + so original goto out is now wrong and will double-mmput() mm_struct. Fix + by jumping further to clean up only vm_file and name_buf. + + Link: https://lkml.kernel.org/r/20260210192738.3041609-1-andrii@kernel.org + Fixes: b5cbacd7f86f ("procfs: avoid fetching build ID while holding VMA lock") + Signed-off-by: Andrii Nakryiko + Reported-by: Ruikai Peng + Reported-by: Thomas Gleixner + Tested-by: Thomas Gleixner + Reviewed-by: Shakeel Butt + Reported-by: syzbot+237b5b985b78c1da9600@syzkaller.appspotmail.com + Cc: Ruikai Peng + Closes: https://lkml.kernel.org/r/CAFD3drOJANTZPuyiqMdqpiRwOKnHwv5QgMNZghCDr-WxdiHvMg@mail.gmail.com + Closes: https://lore.kernel.org/all/698aaf3c.050a0220.3b3015.0088.GAE@google.com/T/#u + Cc: + Signed-off-by: Andrew Morton + +Signed-off-by: Rafael Aquini + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 27cc491..a574e8d 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -581,7 +581,7 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + } else { + if (karg.build_id_size < build_id_sz) { + err = -ENAMETOOLONG; +- goto out; ++ goto out_file; + } + karg.build_id_size = build_id_sz; + } +@@ -609,6 +609,7 @@ static int do_procmap_query(struct proc_maps_private *priv, void __user *uarg) + out: + query_vma_teardown(mm, vma); + mmput(mm); ++out_file: + if (vm_file) + fput(vm_file); + kfree(name_buf); diff --git a/1104-drm-i915-alpm-alpm-disable-fixes.patch b/1104-drm-i915-alpm-alpm-disable-fixes.patch new file mode 100644 index 000000000..9d418fcd4 --- /dev/null +++ b/1104-drm-i915-alpm-alpm-disable-fixes.patch @@ -0,0 +1,43 @@ +From eb4a7139e97374f42b7242cc754e77f1623fbcd5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jouni=20H=C3=B6gander?= +Date: Thu, 12 Feb 2026 08:27:31 +0200 +Subject: [PATCH] drm/i915/alpm: ALPM disable fixes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PORT_ALPM_CTL is supposed to be written only before link training. Remove +writing it from ALPM disable. + +Also clearing ALPM_CTL_ALPM_AUX_LESS_ENABLE and is not about disabling ALPM +but switching to AUX-Wake ALPM. Stop touching this bit on ALPM disable. + +Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/7153 +Fixes: 1ccbf135862b ("drm/i915/psr: Enable ALPM on source side for eDP Panel replay") +Cc: Animesh Manna +Cc: Jani Nikula +Cc: # v6.10+ +Signed-off-by: Jouni Högander +Reviewed-by: Michał Grzelak +Link: https://patch.msgid.link/20260212062731.397801-1-jouni.hogander@intel.com +(cherry picked from commit 008304c9ae75c772d3460040de56e12112cdf5e6) +Signed-off-by: Joonas Lahtinen + +diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c +index ed7a7ed..2aed386 100644 +--- a/drivers/gpu/drm/i915/display/intel_alpm.c ++++ b/drivers/gpu/drm/i915/display/intel_alpm.c +@@ -577,12 +577,7 @@ void intel_alpm_disable(struct intel_dp *intel_dp) + mutex_lock(&intel_dp->alpm_parameters.lock); + + intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder), +- ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE | +- ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); +- +- intel_de_rmw(display, +- PORT_ALPM_CTL(cpu_transcoder), +- PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); ++ ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE, 0); + + drm_dbg_kms(display->drm, "Disabling ALPM\n"); + mutex_unlock(&intel_dp->alpm_parameters.lock); diff --git a/1105-drm-i915-psr-don-t-enable-panel-replay-on-sink-if-globally-disabled.patch b/1105-drm-i915-psr-don-t-enable-panel-replay-on-sink-if-globally-disabled.patch new file mode 100644 index 000000000..e5275a8e0 --- /dev/null +++ b/1105-drm-i915-psr-don-t-enable-panel-replay-on-sink-if-globally-disabled.patch @@ -0,0 +1,47 @@ +From 69f83f167463bad26104af7fbc114ce1f80366b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jouni=20H=C3=B6gander?= +Date: Thu, 15 Jan 2026 09:00:39 +0200 +Subject: [PATCH] drm/i915/psr: Don't enable Panel Replay on sink if globally + disabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With some panels informing support for Panel Replay we are observing +problems if having Panel Replay enable bit set on sink when forced to use +PSR instead of Panel Replay. Avoid these problems by not setting Panel +Replay enable bit in sink when Panel Replay is globally disabled during +link training. I.e. disabled by module parameter. + +The enable bit is still set when disabling Panel Replay via debugfs +interface. Added note comment about this. + +Fixes: 68f3a505b367 ("drm/i915/psr: Enable Panel Replay on sink always when it's supported") +Cc: Mika Kahola +Cc: Jani Nikula +Cc: Rodrigo Vivi +Cc: # v6.15+ +Signed-off-by: Jouni Högander +Reviewed-by: Mika Kahola +Link: https://patch.msgid.link/20260115070039.368965-1-jouni.hogander@intel.com +(cherry picked from commit c5a52cd04e24f0ae53fda26f74ab027b8c548e0e) +Signed-off-by: Joonas Lahtinen + +diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c +index 5adbf7a..69cbaa5 100644 +--- a/drivers/gpu/drm/i915/display/intel_psr.c ++++ b/drivers/gpu/drm/i915/display/intel_psr.c +@@ -856,7 +856,12 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp, + + void intel_psr_panel_replay_enable_sink(struct intel_dp *intel_dp) + { +- if (CAN_PANEL_REPLAY(intel_dp)) ++ /* ++ * NOTE: We might want to trigger mode set when ++ * disabling/enabling Panel Replay via debugfs interface to ++ * ensure this bit is cleared/set accordingly. ++ */ ++ if (CAN_PANEL_REPLAY(intel_dp) && panel_replay_global_enabled(intel_dp)) + drm_dp_dpcd_writeb(&intel_dp->aux, PANEL_REPLAY_CONFIG, + DP_PANEL_REPLAY_ENABLE); + } diff --git a/1106-drm-i915-psr-block-dc-states-on-vblank-enable-when-panel-replay-supported.patch b/1106-drm-i915-psr-block-dc-states-on-vblank-enable-when-panel-replay-supported.patch new file mode 100644 index 000000000..0c15fdf13 --- /dev/null +++ b/1106-drm-i915-psr-block-dc-states-on-vblank-enable-when-panel-replay-supported.patch @@ -0,0 +1,72 @@ +From 8bb9093df555f9e89fdbe1405118b11384c03e04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jouni=20H=C3=B6gander?= +Date: Wed, 20 May 2026 13:49:43 +0300 +Subject: [PATCH] drm/i915/psr: Block DC states on vblank enable when Panel + Replay supported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently we are blocking DC states only when Panel Replay is enabled on +vblank enable. It may happen that Panel Replay is getting enabled when +vblank is already enabled. Fix this by blocking DC states always if Panel +Replay is supported. + +While at it take care of possible dual eDP case by looping all encoders +supporting PSR. + +Fixes: 0c427ac78a1d ("drm/i915/psr: Add interface to notify PSR of vblank enable/disable") +Cc: # v6.16+ +Signed-off-by: Jouni Högander +Reviewed-by: Michał Grzelak +Link: https://patch.msgid.link/20260520104944.239797-1-jouni.hogander@intel.com +(cherry picked from commit eb5911f990554f7ce947dd53df00c114362e4465) +Signed-off-by: Tvrtko Ursulin + +diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c +index 69cbaa5..c805c69 100644 +--- a/drivers/gpu/drm/i915/display/intel_psr.c ++++ b/drivers/gpu/drm/i915/display/intel_psr.c +@@ -3984,32 +3984,33 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, + bool enable) + { + struct intel_encoder *encoder; ++ bool block_dc_states = false; + + for_each_intel_encoder_with_psr(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_lock(&intel_dp->psr.lock); +- if (intel_dp->psr.panel_replay_enabled) { +- mutex_unlock(&intel_dp->psr.lock); +- break; +- } ++ if (CAN_PANEL_REPLAY(intel_dp)) ++ block_dc_states = true; + +- if (intel_dp->psr.enabled && intel_dp->psr.pkg_c_latency_used) ++ if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled && ++ intel_dp->psr.pkg_c_latency_used) + intel_psr_apply_underrun_on_idle_wa_locked(intel_dp); + + mutex_unlock(&intel_dp->psr.lock); +- return; + } + + /* + * NOTE: intel_display_power_set_target_dc_state is used +- * only by PSR * code for DC3CO handling. DC3CO target ++ * only by PSR code for DC3CO handling. DC3CO target + * state is currently disabled in * PSR code. If DC3CO + * is taken into use we need take that into account here + * as well. + */ +- intel_display_power_set_target_dc_state(display, enable ? DC_STATE_DISABLE : +- DC_STATE_EN_UPTO_DC6); ++ if (block_dc_states) ++ intel_display_power_set_target_dc_state(display, enable ? ++ DC_STATE_DISABLE : ++ DC_STATE_EN_UPTO_DC6); + } + + static void diff --git a/1107-drm-i915-psr-use-dc-off-wake-reference-to-block-dc6-on-vblank-enable.patch b/1107-drm-i915-psr-use-dc-off-wake-reference-to-block-dc6-on-vblank-enable.patch new file mode 100644 index 000000000..d1285141a --- /dev/null +++ b/1107-drm-i915-psr-use-dc-off-wake-reference-to-block-dc6-on-vblank-enable.patch @@ -0,0 +1,139 @@ +From 3549a9649dc7c5fc586ab12f675279283cdcb2a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jouni=20H=C3=B6gander?= +Date: Wed, 20 May 2026 13:49:44 +0300 +Subject: [PATCH] drm/i915/psr: Use DC_OFF wake reference to block DC6 on + vblank enable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We are observing following warnings: + +*ERROR* power well DC_off state mismatch (refcount 0/enabled 1) + +gen9_dc_off_power_well_enabled is considering target state DC_STATE_DISABLE +as DC_OFF power well being enabled. Fix this by using wakeref for the +purpose. + +To achieve this we need to modify notification code as well. Currently it +is possible that PSR gets notified vblank enable/disable twice on same +status. This is currently not a problem as it is just triggering call to +intel_display_power_set_target_dc_state with same target state as a +parameter. When using wakeref this becomes a problem due to reference +counting. Fix this storing vbank status on last notification and use that +to ensure there are no more than one notification with same vblank status. + +v2: ensure there is no subsequent notifications with same status + +Fixes: aa451abcffb5 ("drm/i915/display: Prevent DC6 while vblank is enabled for Panel Replay") +Cc: # v6.13+ +Signed-off-by: Jouni Högander +Reviewed-by: Michał Grzelak +Link: https://patch.msgid.link/20260520104944.239797-2-jouni.hogander@intel.com +(cherry picked from commit 35485ac56d878192a3829a58cb26503125ec7104) +Signed-off-by: Tvrtko Ursulin + +diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h +index 8c22640..800a30b 100644 +--- a/drivers/gpu/drm/i915/display/intel_display_core.h ++++ b/drivers/gpu/drm/i915/display/intel_display_core.h +@@ -472,6 +472,7 @@ struct intel_display { + u8 vblank_enabled; + + int vblank_enable_count; ++ bool vblank_status_last_notified; + + struct work_struct vblank_notify_work; + +diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c +index 123e054..21b2a19 100644 +--- a/drivers/gpu/drm/i915/display/intel_display_irq.c ++++ b/drivers/gpu/drm/i915/display/intel_display_irq.c +@@ -1707,8 +1707,12 @@ static void intel_display_vblank_notify_work(struct work_struct *work) + struct intel_display *display = + container_of(work, typeof(*display), irq.vblank_notify_work); + int vblank_enable_count = READ_ONCE(display->irq.vblank_enable_count); ++ bool vblank_status = !!vblank_enable_count; + +- intel_psr_notify_vblank_enable_disable(display, vblank_enable_count); ++ if (display->irq.vblank_status_last_notified != vblank_status) { ++ intel_psr_notify_vblank_enable_disable(display, vblank_status); ++ display->irq.vblank_status_last_notified = vblank_status; ++ } + } + + int bdw_enable_vblank(struct drm_crtc *_crtc) +@@ -1721,10 +1725,10 @@ int bdw_enable_vblank(struct drm_crtc *_crtc) + if (gen11_dsi_configure_te(crtc, true)) + return 0; + ++ spin_lock_irqsave(&display->irq.lock, irqflags); + if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0) + schedule_work(&display->irq.vblank_notify_work); + +- spin_lock_irqsave(&display->irq.lock, irqflags); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); + spin_unlock_irqrestore(&display->irq.lock, irqflags); + +diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h +index 9995663..05da837 100644 +--- a/drivers/gpu/drm/i915/display/intel_display_types.h ++++ b/drivers/gpu/drm/i915/display/intel_display_types.h +@@ -1700,6 +1700,10 @@ struct intel_psr { + bool pkg_c_latency_used; + + u8 active_non_psr_pipes; ++ ++ const char *no_psr_reason; ++ ++ struct ref_tracker *vblank_wakeref; + }; + + struct intel_dp { +diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c +index c805c69..4747cff 100644 +--- a/drivers/gpu/drm/i915/display/intel_psr.c ++++ b/drivers/gpu/drm/i915/display/intel_psr.c +@@ -3984,14 +3984,20 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, + bool enable) + { + struct intel_encoder *encoder; +- bool block_dc_states = false; + + for_each_intel_encoder_with_psr(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_lock(&intel_dp->psr.lock); +- if (CAN_PANEL_REPLAY(intel_dp)) +- block_dc_states = true; ++ if (CAN_PANEL_REPLAY(intel_dp)) { ++ if (enable) ++ intel_dp->psr.vblank_wakeref = ++ intel_display_power_get(display, ++ POWER_DOMAIN_DC_OFF); ++ else ++ intel_display_power_put(display, POWER_DOMAIN_DC_OFF, ++ intel_dp->psr.vblank_wakeref); ++ } + + if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled && + intel_dp->psr.pkg_c_latency_used) +@@ -3999,18 +4005,6 @@ void intel_psr_notify_vblank_enable_disable(struct intel_display *display, + + mutex_unlock(&intel_dp->psr.lock); + } +- +- /* +- * NOTE: intel_display_power_set_target_dc_state is used +- * only by PSR code for DC3CO handling. DC3CO target +- * state is currently disabled in * PSR code. If DC3CO +- * is taken into use we need take that into account here +- * as well. +- */ +- if (block_dc_states) +- intel_display_power_set_target_dc_state(display, enable ? +- DC_STATE_DISABLE : +- DC_STATE_EN_UPTO_DC6); + } + + static void diff --git a/1108-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch b/1108-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch new file mode 100644 index 000000000..dd222a46a --- /dev/null +++ b/1108-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch @@ -0,0 +1,79 @@ +From 7c9c0da42abb4835933201861f979a5ef152f185 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Tue, 12 May 2026 13:04:40 +0200 +Subject: [PATCH] dpll: export __dpll_pin_change_ntf() for use under dpll_lock + +JIRA: https://redhat.atlassian.net/browse/RHEL-137412 + +commit 620055cb1036a6125fd912e7a14b47a6572b809b +Author: Ivan Vecera +Date: Mon Apr 27 22:22:21 2026 -0700 + + dpll: export __dpll_pin_change_ntf() for use under dpll_lock + + Export __dpll_pin_change_ntf() so that drivers can send pin change + notifications from within pin callbacks, which are already called + under dpll_lock. Using dpll_pin_change_ntf() in that context would + deadlock. + + Add lockdep_assert_held() to catch misuse without the lock held. + + Acked-by: Vadim Fedorenko + Signed-off-by: Ivan Vecera + Signed-off-by: Petr Oros + Tested-by: Alexander Nowlin + Reviewed-by: Arkadiusz Kubalewski + Signed-off-by: Jacob Keller + Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-9-cdcb48303fd8@intel.com + Signed-off-by: Paolo Abeni + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index 1d860eb..6c28b8f 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -938,11 +938,21 @@ int dpll_pin_delete_ntf(struct dpll_pin *pin) + return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); + } + ++/** ++ * __dpll_pin_change_ntf - notify that the pin has been changed ++ * @pin: registered pin pointer ++ * ++ * Context: caller must hold dpll_lock. Suitable for use inside pin ++ * callbacks which are already invoked under dpll_lock. ++ * Return: 0 if succeeds, error code otherwise. ++ */ + int __dpll_pin_change_ntf(struct dpll_pin *pin) + { ++ lockdep_assert_held(&dpll_lock); + dpll_pin_notify(pin, DPLL_PIN_CHANGED); + return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); + } ++EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf); + + /** + * dpll_pin_change_ntf - notify that the pin has been changed +diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h +index dd28b56..a9cfd55 100644 +--- a/drivers/dpll/dpll_netlink.h ++++ b/drivers/dpll/dpll_netlink.h +@@ -11,5 +11,3 @@ int dpll_device_delete_ntf(struct dpll_device *dpll); + int dpll_pin_create_ntf(struct dpll_pin *pin); + + int dpll_pin_delete_ntf(struct dpll_pin *pin); +- +-int __dpll_pin_change_ntf(struct dpll_pin *pin); +diff --git a/include/linux/dpll.h b/include/linux/dpll.h +index d988c09..4a8854a 100644 +--- a/include/linux/dpll.h ++++ b/include/linux/dpll.h +@@ -338,6 +338,7 @@ int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin, + + int dpll_device_change_ntf(struct dpll_device *dpll); + ++int __dpll_pin_change_ntf(struct dpll_pin *pin); + int dpll_pin_change_ntf(struct dpll_pin *pin); + + int register_dpll_notifier(struct notifier_block *nb); diff --git a/1109-dpll-prevent-duplicate-registrations.patch b/1109-dpll-prevent-duplicate-registrations.patch new file mode 100644 index 000000000..079070029 --- /dev/null +++ b/1109-dpll-prevent-duplicate-registrations.patch @@ -0,0 +1,67 @@ +From 67455700958bf8d6868d2ba366556948f36b17b1 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:47 +0200 +Subject: [PATCH] dpll: Prevent duplicate registrations + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit f3ddbaaaaf4d0633b40482f471753f9c71294a4a +Author: Ivan Vecera +Date: Wed Jan 21 14:00:11 2026 +0100 + + dpll: Prevent duplicate registrations + + Modify the internal registration helpers dpll_xa_ref_{dpll,pin}_add() + to reject duplicate registration attempts. + + Previously, if a caller attempted to register the same pin multiple + times (with the same ops, priv, and cookie) on the same device, the core + silently increments the reference count and return success. This behavior + is incorrect because if the caller makes these duplicate registrations + then for the first one dpll_pin_registration is allocated and for others + the associated dpll_pin_ref.refcount is incremented. During the first + unregistration the associated dpll_pin_registration is freed and for + others WARN is fired. + + Fix this by updating the logic to return `-EEXIST` if a matching + registration is found to enforce a strict "register once" policy. + + Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions") + Signed-off-by: Ivan Vecera + Reviewed-by: Arkadiusz Kubalewski + Reviewed-by: Vadim Fedorenko + Link: https://patch.msgid.link/20260121130012.112606-1-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 8b260a3..f1b76fc 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -198,10 +198,8 @@ dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, + if (ref->pin != pin) + continue; + reg = dpll_pin_registration_find(ref, ops, priv, cookie); +- if (reg) { +- refcount_inc(&ref->refcount); +- return 0; +- } ++ if (reg) ++ return -EEXIST; + ref_exists = true; + break; + } +@@ -281,10 +279,8 @@ dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, + if (ref->dpll != dpll) + continue; + reg = dpll_pin_registration_find(ref, ops, priv, cookie); +- if (reg) { +- refcount_inc(&ref->refcount); +- return 0; +- } ++ if (reg) ++ return -EEXIST; + ref_exists = true; + break; + } diff --git a/1110-dpll-zl3073x-use-named-initializers-for-struct-i2c-device-id.patch b/1110-dpll-zl3073x-use-named-initializers-for-struct-i2c-device-id.patch new file mode 100644 index 000000000..48d68a2db --- /dev/null +++ b/1110-dpll-zl3073x-use-named-initializers-for-struct-i2c-device-id.patch @@ -0,0 +1,54 @@ +From c9a2d9869828d1f8e0c86f78358c0f36aa75a632 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:50 +0200 +Subject: [PATCH] dpll: zl3073x: Use named initializers for struct + i2c_device_id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit a09dfac0296dff2521bf53b8f53a7c0d83607782 +Author: Uwe Kleine-König (The Capable Hub) +Date: Tue May 19 16:27:10 2026 +0200 + + dpll: zl3073x: Use named initializers for struct i2c_device_id + + While being less compact, using named initializers allows to more easily + see which members of the structs are assigned which value without having + to lookup the declaration of the struct. And it's also more robust + against changes to the struct definition. + + This patch doesn't modify the compiled arrays, only their representation + in source form benefits. The former was confirmed with x86 and arm64 + builds. + + Signed-off-by: Uwe Kleine-König (The Capable Hub) + Reviewed-by: Ivan Vecera + Link: https://patch.msgid.link/20260519142710.1587324-2-u.kleine-koenig@baylibre.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/zl3073x/i2c.c b/drivers/dpll/zl3073x/i2c.c +index 979df85..4a23340 100644 +--- a/drivers/dpll/zl3073x/i2c.c ++++ b/drivers/dpll/zl3073x/i2c.c +@@ -26,11 +26,11 @@ static int zl3073x_i2c_probe(struct i2c_client *client) + } + + static const struct i2c_device_id zl3073x_i2c_id[] = { +- { "zl30731" }, +- { "zl30732" }, +- { "zl30733" }, +- { "zl30734" }, +- { "zl30735" }, ++ { .name = "zl30731" }, ++ { .name = "zl30732" }, ++ { .name = "zl30733" }, ++ { .name = "zl30734" }, ++ { .name = "zl30735" }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(i2c, zl3073x_i2c_id); diff --git a/1111-dpll-zl3073x-fix-memory-leak-on-pin-registration-failure.patch b/1111-dpll-zl3073x-fix-memory-leak-on-pin-registration-failure.patch new file mode 100644 index 000000000..cbe14e974 --- /dev/null +++ b/1111-dpll-zl3073x-fix-memory-leak-on-pin-registration-failure.patch @@ -0,0 +1,60 @@ +From a0afb5efe1c574c74950558f3286dbbb78ada44f Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:51 +0200 +Subject: [PATCH] dpll: zl3073x: fix memory leak on pin registration failure + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit fa997ddef508b1b37b2fe4d2dad7c4b70958335e +Author: Ivan Vecera +Date: Tue May 19 15:22:05 2026 +0200 + + dpll: zl3073x: fix memory leak on pin registration failure + + If zl3073x_dpll_pin_register() fails, the allocated pin is not yet + added to zldpll->pins list. The error path calls + zl3073x_dpll_pins_unregister() which only iterates pins on the list, + so the current pin is leaked. Free the pin before jumping to the error + label. + + Additionally move the pin->dpll_pin = NULL assignment in + zl3073x_dpll_pin_register() from err_register to the common + err_pin_get path. When dpll_pin_get() fails, pin->dpll_pin holds an + ERR_PTR value. Without this fix the subsequent zl3073x_dpll_pin_free() + would trigger a spurious WARN because it checks pin->dpll_pin for + non-NULL. + + Fixes: 75a71ecc2412 ("dpll: zl3073x: Register DPLL devices and pins") + Reviewed-by: Petr Oros + Signed-off-by: Ivan Vecera + Link: https://patch.msgid.link/20260519132205.161847-1-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c +index 6b714ec..03ee4df 100644 +--- a/drivers/dpll/zl3073x/dpll.c ++++ b/drivers/dpll/zl3073x/dpll.c +@@ -1434,8 +1434,8 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin *pin, u32 index) + + err_register: + dpll_pin_put(pin->dpll_pin, &pin->tracker); +- pin->dpll_pin = NULL; + err_pin_get: ++ pin->dpll_pin = NULL; + fwnode_handle_put(pin->fwnode); + pin->fwnode = NULL; + zl3073x_pin_props_put(props); +@@ -1603,8 +1603,10 @@ zl3073x_dpll_pins_register(struct zl3073x_dpll *zldpll) + } + + rc = zl3073x_dpll_pin_register(pin, index); +- if (rc) ++ if (rc) { ++ zl3073x_dpll_pin_free(pin); + goto error; ++ } + + list_add(&pin->list, &zldpll->pins); + } diff --git a/1112-dpll-change-dpll-netdev-pin-handle-size-to-assume-dpll-a-pin-id-will-be-used.patch b/1112-dpll-change-dpll-netdev-pin-handle-size-to-assume-dpll-a-pin-id-will-be-used.patch new file mode 100644 index 000000000..6897ebba6 --- /dev/null +++ b/1112-dpll-change-dpll-netdev-pin-handle-size-to-assume-dpll-a-pin-id-will-be-used.patch @@ -0,0 +1,110 @@ +From 5106bbc6e840150a786f93951713a2d122be7cdc Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:53 +0200 +Subject: [PATCH] dpll: change dpll_netdev_pin_handle_size() to assume + DPLL_A_PIN_ID will be used + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 7409fad779e271f252d844ae16e1a7429626b13e +Author: Eric Dumazet +Date: Thu May 21 17:14:39 2026 +0000 + + dpll: change dpll_netdev_pin_handle_size() to assume DPLL_A_PIN_ID will be used + + We plan to no longer hold RTNL in "ip link show", and use RCU instead. + + Assume rtnl_fill_dpll_pin() will have to fill DPLL_A_PIN_ID. + + It is fine to over-estimate skb size (by 8 bytes) in if_nlmsg_size(). + + Signed-off-by: Eric Dumazet + Reviewed-by: Vadim Fedorenko + Link: https://patch.msgid.link/20260521171440.114956-1-edumazet@google.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index 6c28b8f..2604fa9 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -89,17 +89,6 @@ static struct dpll_pin *dpll_netdev_pin(const struct net_device *dev) + return rcu_dereference_rtnl(dev->dpll_pin); + } + +-/** +- * dpll_netdev_pin_handle_size - get size of pin handle attribute of a netdev +- * @dev: netdev from which to get the pin +- * +- * Return: byte size of pin handle attribute, or 0 if @dev has no pin. +- */ +-size_t dpll_netdev_pin_handle_size(const struct net_device *dev) +-{ +- return dpll_netdev_pin(dev) ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */ +-} +- + int dpll_netdev_add_pin_handle(struct sk_buff *msg, + const struct net_device *dev) + { +diff --git a/include/linux/dpll.h b/include/linux/dpll.h +index 4a8854a..ff7ff18 100644 +--- a/include/linux/dpll.h ++++ b/include/linux/dpll.h +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + #include + +@@ -270,7 +271,11 @@ struct dpll_pin_notifier_info { + void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin); + void dpll_netdev_pin_clear(struct net_device *dev); + +-size_t dpll_netdev_pin_handle_size(const struct net_device *dev); ++static inline size_t dpll_netdev_pin_handle_size(void) ++{ ++ return nla_total_size(4); /* DPLL_A_PIN_ID */ ++} ++ + int dpll_netdev_add_pin_handle(struct sk_buff *msg, + const struct net_device *dev); + +@@ -281,7 +286,7 @@ static inline void + dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { } + static inline void dpll_netdev_pin_clear(struct net_device *dev) { } + +-static inline size_t dpll_netdev_pin_handle_size(const struct net_device *dev) ++static inline size_t dpll_netdev_pin_handle_size(void) + { + return 0; + } +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 10a6a25..a0b5d5a 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1087,11 +1087,11 @@ static size_t rtnl_devlink_port_size(const struct net_device *dev) + return size; + } + +-static size_t rtnl_dpll_pin_size(const struct net_device *dev) ++static size_t rtnl_dpll_pin_size(void) + { + size_t size = nla_total_size(0); /* nest IFLA_DPLL_PIN */ + +- size += dpll_netdev_pin_handle_size(dev); ++ size += dpll_netdev_pin_handle_size(); + + return size; + } +@@ -1152,7 +1152,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + + rtnl_prop_list_size(dev) + + nla_total_size(MAX_ADDR_LEN) /* IFLA_PERM_ADDRESS */ + + rtnl_devlink_port_size(dev) +- + rtnl_dpll_pin_size(dev) ++ + rtnl_dpll_pin_size() + + nla_total_size(8) /* IFLA_MAX_PACING_OFFLOAD_HORIZON */ + + 0; + } diff --git a/1113-dpll-export-dpll-device-change-ntf-for-use-under-dpll-lock.patch b/1113-dpll-export-dpll-device-change-ntf-for-use-under-dpll-lock.patch new file mode 100644 index 000000000..10ffb39d5 --- /dev/null +++ b/1113-dpll-export-dpll-device-change-ntf-for-use-under-dpll-lock.patch @@ -0,0 +1,68 @@ +From 41e5e87efc968b8591fb46e1014469d697031e82 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:55 +0200 +Subject: [PATCH] dpll: export __dpll_device_change_ntf() for use under + dpll_lock + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 20040b2a3cb992f84d3db4c086b909eb9b906b31 +Author: Ivan Vecera +Date: Tue May 26 09:45:23 2026 +0200 + + dpll: export __dpll_device_change_ntf() for use under dpll_lock + + Export __dpll_device_change_ntf() so that drivers can send device + change notifications from within device callbacks, which are already + called under dpll_lock. Using dpll_device_change_ntf() in that + context would deadlock. + + Add lockdep_assert_held() to catch misuse without the lock held. + + Signed-off-by: Ivan Vecera + Reviewed-by: Jiri Pirko + Link: https://patch.msgid.link/20260526074525.1451008-2-ivecera@redhat.com + Signed-off-by: Paolo Abeni + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index 2604fa9..7a86b86 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -856,12 +856,21 @@ int dpll_device_delete_ntf(struct dpll_device *dpll) + return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll); + } + +-static int +-__dpll_device_change_ntf(struct dpll_device *dpll) ++/** ++ * __dpll_device_change_ntf - notify that the dpll device has been changed ++ * @dpll: registered dpll pointer ++ * ++ * Context: caller must hold dpll_lock. Suitable for use inside device ++ * callbacks which are already invoked under dpll_lock. ++ * Return: 0 if succeeds, error code otherwise. ++ */ ++int __dpll_device_change_ntf(struct dpll_device *dpll) + { ++ lockdep_assert_held(&dpll_lock); + dpll_device_notify(dpll, DPLL_DEVICE_CHANGED); + return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll); + } ++EXPORT_SYMBOL_GPL(__dpll_device_change_ntf); + + /** + * dpll_device_change_ntf - notify that the dpll device has been changed +diff --git a/include/linux/dpll.h b/include/linux/dpll.h +index ff7ff18..5ee402f 100644 +--- a/include/linux/dpll.h ++++ b/include/linux/dpll.h +@@ -341,6 +341,7 @@ void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin, + struct dpll_pin *ref_sync_pin); + ++int __dpll_device_change_ntf(struct dpll_device *dpll); + int dpll_device_change_ntf(struct dpll_device *dpll); + + int __dpll_pin_change_ntf(struct dpll_pin *pin); diff --git a/1114-dpll-zl3073x-use-dpll-device-change-ntf-and-remove-change-work.patch b/1114-dpll-zl3073x-use-dpll-device-change-ntf-and-remove-change-work.patch new file mode 100644 index 000000000..b69ef627f --- /dev/null +++ b/1114-dpll-zl3073x-use-dpll-device-change-ntf-and-remove-change-work.patch @@ -0,0 +1,113 @@ +From 4177e352ca1390d614e458e8a0929a63ba6a17e3 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:13:57 +0200 +Subject: [PATCH] dpll: zl3073x: use __dpll_device_change_ntf() and remove + change_work + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit d733f519f6443540f8359461a34e3b0042099bbe +Author: Ivan Vecera +Date: Tue May 26 09:45:24 2026 +0200 + + dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work + + The change_work was introduced to send device change notifications + from DPLL device callbacks without deadlocking on dpll_lock, since + the callbacks are already invoked under that lock. Now that + __dpll_device_change_ntf() is exported for callers that already + hold dpll_lock, use it directly and remove the change_work + infrastructure entirely. + + This eliminates a race condition where change_work could be + re-scheduled after cancel_work_sync() during device teardown, + potentially causing the handler to dereference a freed or NULL + dpll_dev pointer. + + Fixes: 9363b4837659 ("dpll: zl3073x: Allow to configure phase offset averaging factor") + Signed-off-by: Ivan Vecera + Link: https://patch.msgid.link/20260526074525.1451008-3-ivecera@redhat.com + Signed-off-by: Paolo Abeni + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c +index 03ee4df..98750f3 100644 +--- a/drivers/dpll/zl3073x/dpll.c ++++ b/drivers/dpll/zl3073x/dpll.c +@@ -1117,15 +1117,6 @@ zl3073x_dpll_phase_offset_avg_factor_get(const struct dpll_device *dpll, + return 0; + } + +-static void +-zl3073x_dpll_change_work(struct work_struct *work) +-{ +- struct zl3073x_dpll *zldpll; +- +- zldpll = container_of(work, struct zl3073x_dpll, change_work); +- dpll_device_change_ntf(zldpll->dpll_dev); +-} +- + static int + zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll, + void *dpll_priv, u32 factor, +@@ -1151,8 +1142,10 @@ zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll, + * we have to send a notification for other DPLL devices. + */ + list_for_each_entry(item, &zldpll->dev->dplls, list) { +- if (item != zldpll) +- schedule_work(&item->change_work); ++ struct dpll_device *dpll_dev = READ_ONCE(item->dpll_dev); ++ ++ if (item != zldpll && dpll_dev) ++ __dpll_device_change_ntf(dpll_dev); + } + + return 0; +@@ -1667,13 +1660,13 @@ zl3073x_dpll_device_register(struct zl3073x_dpll *zldpll) + static void + zl3073x_dpll_device_unregister(struct zl3073x_dpll *zldpll) + { +- WARN(!zldpll->dpll_dev, "DPLL device is not registered\n"); ++ struct dpll_device *dpll_dev = READ_ONCE(zldpll->dpll_dev); + +- cancel_work_sync(&zldpll->change_work); ++ WARN(!dpll_dev, "DPLL device is not registered\n"); + +- dpll_device_unregister(zldpll->dpll_dev, &zldpll->ops, zldpll); +- dpll_device_put(zldpll->dpll_dev, &zldpll->tracker); +- zldpll->dpll_dev = NULL; ++ WRITE_ONCE(zldpll->dpll_dev, NULL); ++ dpll_device_unregister(dpll_dev, &zldpll->ops, zldpll); ++ dpll_device_put(dpll_dev, &zldpll->tracker); + } + + /** +@@ -1958,7 +1951,6 @@ zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch) + zldpll->dev = zldev; + zldpll->id = ch; + INIT_LIST_HEAD(&zldpll->pins); +- INIT_WORK(&zldpll->change_work, zl3073x_dpll_change_work); + + return zldpll; + } +diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h +index 434c32a..c8bc843 100644 +--- a/drivers/dpll/zl3073x/dpll.h ++++ b/drivers/dpll/zl3073x/dpll.h +@@ -21,7 +21,6 @@ + * @tracker: tracking object for the acquired reference + * @lock_status: last saved DPLL lock status + * @pins: list of pins +- * @change_work: device change notification work + */ + struct zl3073x_dpll { + struct list_head list; +@@ -35,7 +34,6 @@ struct zl3073x_dpll { + dpll_tracker tracker; + enum dpll_lock_status lock_status; + struct list_head pins; +- struct work_struct change_work; + }; + + struct zl3073x_dpll *zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch); diff --git a/1115-dpll-zl3073x-make-frequency-monitor-a-per-device-attribute.patch b/1115-dpll-zl3073x-make-frequency-monitor-a-per-device-attribute.patch new file mode 100644 index 000000000..40bd30917 --- /dev/null +++ b/1115-dpll-zl3073x-make-frequency-monitor-a-per-device-attribute.patch @@ -0,0 +1,195 @@ +From 057880fb4e1f962b89823aa4ad489c36f8fad099 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:00 +0200 +Subject: [PATCH] dpll: zl3073x: make frequency monitor a per-device attribute + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +Conflicts: + - One line context difference in zl3073x_dev_periodic_work() + due to already backported 54e65df8cf18a ("dpll: zl3073x: + report FFO as DPLL vs input reference offset"). + - A fake conflict in zl3073x_dpll_freq_monitor_set() due to + the upstream and downstream diff being rendered differently, + but representing exactly the same code change. + +commit c1224569cef038b040db0459510cd7948ecd467b +Author: Ivan Vecera +Date: Tue May 26 09:45:25 2026 +0200 + + dpll: zl3073x: make frequency monitor a per-device attribute + + The frequency monitoring feature uses shared hardware registers + that measure input reference frequencies independently of + individual DPLL channels. However, the freq_monitor flag was + incorrectly placed in the per-DPLL structure, causing each + channel to track its own enable/disable state independently. + + Since the DPLL core calls measured_freq_get() only for the first + pin registration, the measured_freq_check() in the periodic worker + was gated by the per-DPLL freq_monitor flag of whichever channel + happens to be checked. If the first DPLL channel had frequency + monitoring disabled while another had it enabled, measurements + were never reported. + + Move freq_monitor from struct zl3073x_dpll to struct zl3073x_dev + so all DPLL channels share a single flag, matching the hardware + behavior. Update freq_monitor_set() to notify other DPLL devices + about the change (like phase_offset_avg_factor_set() already does) + and remove the mode-dependent guard in zl3073x_dpll_changes_check() + since all input pin monitoring (pin state, phase offset, FFO, and + measured frequency) works correctly in all DPLL modes. + + Fixes: bfc923b642874 ("dpll: zl3073x: implement frequency monitoring") + Signed-off-by: Ivan Vecera + Link: https://patch.msgid.link/20260526074525.1451008-4-ivecera@redhat.com + Signed-off-by: Paolo Abeni + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c +index b334506..8e6416a 100644 +--- a/drivers/dpll/zl3073x/core.c ++++ b/drivers/dpll/zl3073x/core.c +@@ -724,18 +724,15 @@ zl3073x_dev_periodic_work(struct kthread_work *work) + dev_warn(zldev->dev, "Failed to update phase offsets: %pe\n", + ERR_PTR(rc)); + +- /* Update measured input reference frequencies if any DPLL has +- * frequency monitoring enabled. ++ /* Update measured input reference frequencies if frequency ++ * monitoring is enabled. + */ +- list_for_each_entry(zldpll, &zldev->dplls, list) { +- if (zldpll->freq_monitor) { +- rc = zl3073x_ref_freq_meas_update(zldev); +- if (rc) +- dev_warn(zldev->dev, +- "Failed to update measured frequencies: %pe\n", +- ERR_PTR(rc)); +- break; +- } ++ if (zldev->freq_monitor) { ++ rc = zl3073x_ref_freq_meas_update(zldev); ++ if (rc) ++ dev_warn(zldev->dev, ++ "Failed to update measured frequencies: %pe\n", ++ ERR_PTR(rc)); + } + + list_for_each_entry(zldpll, &zldev->dplls, list) +diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h +index 9944062..addba37 100644 +--- a/drivers/dpll/zl3073x/core.h ++++ b/drivers/dpll/zl3073x/core.h +@@ -57,6 +57,7 @@ struct zl3073x_chip_info { + * @work: periodic work + * @clock_id: clock id of the device + * @phase_avg_factor: phase offset measurement averaging factor ++ * @freq_monitor: is frequency monitor enabled + */ + struct zl3073x_dev { + struct device *dev; +@@ -77,9 +78,10 @@ struct zl3073x_dev { + struct kthread_worker *kworker; + struct kthread_delayed_work work; + +- /* Devlink parameters */ ++ /* Per-chip parameters */ + u64 clock_id; + u8 phase_avg_factor; ++ bool freq_monitor; + }; + + extern const struct regmap_config zl3073x_regmap_config; +diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c +index 98750f3..9f66aac 100644 +--- a/drivers/dpll/zl3073x/dpll.c ++++ b/drivers/dpll/zl3073x/dpll.c +@@ -1250,7 +1250,7 @@ zl3073x_dpll_freq_monitor_get(const struct dpll_device *dpll, + { + struct zl3073x_dpll *zldpll = dpll_priv; + +- if (zldpll->freq_monitor) ++ if (zldpll->dev->freq_monitor) + *state = DPLL_FEATURE_STATE_ENABLE; + else + *state = DPLL_FEATURE_STATE_DISABLE; +@@ -1264,9 +1264,19 @@ zl3073x_dpll_freq_monitor_set(const struct dpll_device *dpll, + enum dpll_feature_state state, + struct netlink_ext_ack *extack) + { +- struct zl3073x_dpll *zldpll = dpll_priv; ++ struct zl3073x_dpll *item, *zldpll = dpll_priv; ++ ++ zldpll->dev->freq_monitor = (state == DPLL_FEATURE_STATE_ENABLE); ++ ++ /* The frequency monitoring is common for all DPLL channels so after ++ * change we have to send a notification for other DPLL devices. ++ */ ++ list_for_each_entry(item, &zldpll->dev->dplls, list) { ++ struct dpll_device *dpll_dev = READ_ONCE(item->dpll_dev); + +- zldpll->freq_monitor = (state == DPLL_FEATURE_STATE_ENABLE); ++ if (item != zldpll && dpll_dev) ++ __dpll_device_change_ntf(dpll_dev); ++ } + + return 0; + } +@@ -1777,7 +1787,7 @@ zl3073x_dpll_pin_measured_freq_check(struct zl3073x_dpll_pin *pin) + u8 ref_id; + u32 freq; + +- if (!zldpll->freq_monitor) ++ if (!zldpll->dev->freq_monitor) + return false; + + ref_id = zl3073x_input_pin_ref_get(pin->id); +@@ -1810,10 +1820,8 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll) + struct zl3073x_dev *zldev = zldpll->dev; + enum dpll_lock_status lock_status; + struct device *dev = zldev->dev; +- const struct zl3073x_chan *chan; + struct zl3073x_dpll_pin *pin; + int rc; +- u8 mode; + + zldpll->check_count++; + +@@ -1832,15 +1840,6 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll) + dpll_device_change_ntf(zldpll->dpll_dev); + } + +- /* Input pin monitoring does make sense only in automatic +- * or forced reference modes. +- */ +- chan = zl3073x_chan_state_get(zldev, zldpll->id); +- mode = zl3073x_chan_mode_get(chan); +- if (mode != ZL_DPLL_MODE_REFSEL_MODE_AUTO && +- mode != ZL_DPLL_MODE_REFSEL_MODE_REFLOCK) +- return; +- + /* Update phase offset latch registers for this DPLL if the phase + * offset monitor feature is enabled. + */ +diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h +index c8bc843..21adcc1 100644 +--- a/drivers/dpll/zl3073x/dpll.h ++++ b/drivers/dpll/zl3073x/dpll.h +@@ -15,7 +15,6 @@ + * @id: DPLL index + * @check_count: periodic check counter + * @phase_monitor: is phase offset monitor enabled +- * @freq_monitor: is frequency monitor enabled + * @ops: DPLL device operations for this instance + * @dpll_dev: pointer to registered DPLL device + * @tracker: tracking object for the acquired reference +@@ -28,7 +27,6 @@ struct zl3073x_dpll { + u8 id; + u8 check_count; + bool phase_monitor; +- bool freq_monitor; + struct dpll_device_ops ops; + struct dpll_device *dpll_dev; + dpll_tracker tracker; diff --git a/1116-dpll-add-generic-dpll-type.patch b/1116-dpll-add-generic-dpll-type.patch new file mode 100644 index 000000000..e4f6bad3f --- /dev/null +++ b/1116-dpll-add-generic-dpll-type.patch @@ -0,0 +1,84 @@ +From 07f57ff127cd39789c0c0ad8f964e84de6b8065f Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:03 +0200 +Subject: [PATCH] dpll: add generic DPLL type + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 9375487c0c78817b3651e2621d648c6198757c41 +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:33 2026 +0200 + + dpll: add generic DPLL type + + Add DPLL_TYPE_GENERIC to represent DPLL devices which do not fit the + existing PPS or EEC classes. + + The UAPI type is intentionally generic. During netdev discussion, + maintainers pointed out that introducing identifiers tied to a specific + placement or single design does not scale across ASICs and vendors. + The role of a DPLL is already inferable from the spawning driver, + bus device, and pin topology, without encoding additional + purpose-specific taxonomy in the type name. + + Using a generic type keeps the UAPI extensible and avoids premature + naming that may become incorrect as new hardware topologies are + exposed through the DPLL subsystem. + + Expose the new type through UAPI and netlink specification as "generic". + + Reviewed-by: Aleksandr Loktionov + Reviewed-by: Jiri Pirko + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-2-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml +index 4ba8adc..9c5f985 100644 +--- a/Documentation/netlink/specs/dpll.yaml ++++ b/Documentation/netlink/specs/dpll.yaml +@@ -138,6 +138,9 @@ definitions: + - + name: eec + doc: dpll drives the Ethernet Equipment Clock ++ - ++ name: generic ++ doc: generic dpll type for devices outside PPS/EEC classes + render-max: true + - + type: enum +diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c +index 268999d..ad63db3 100644 +--- a/drivers/dpll/dpll_nl.c ++++ b/drivers/dpll/dpll_nl.c +@@ -36,7 +36,7 @@ const struct nla_policy dpll_reference_sync_nl_policy[DPLL_A_PIN_STATE + 1] = { + static const struct nla_policy dpll_device_id_get_nl_policy[DPLL_A_TYPE + 1] = { + [DPLL_A_MODULE_NAME] = { .type = NLA_NUL_STRING, }, + [DPLL_A_CLOCK_ID] = { .type = NLA_U64, }, +- [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 2), ++ [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 3), + }; + + /* DPLL_CMD_DEVICE_GET - do */ +diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h +index aa45b79..7cc709c 100644 +--- a/include/uapi/linux/dpll.h ++++ b/include/uapi/linux/dpll.h +@@ -108,11 +108,14 @@ enum dpll_clock_quality_level { + * enum dpll_type - type of dpll, valid values for DPLL_A_TYPE attribute + * @DPLL_TYPE_PPS: dpll produces Pulse-Per-Second signal + * @DPLL_TYPE_EEC: dpll drives the Ethernet Equipment Clock ++ * @DPLL_TYPE_GENERIC: generic dpll type for devices outside PPS/EEC classes + */ + enum dpll_type { + DPLL_TYPE_PPS = 1, + DPLL_TYPE_EEC, +- ++#ifndef __GENKSYMS__ ++ DPLL_TYPE_GENERIC, ++#endif + /* private: */ + __DPLL_TYPE_MAX, + DPLL_TYPE_MAX = (__DPLL_TYPE_MAX - 1) diff --git a/1117-dpll-allow-registering-fw-identified-pin-with-a-different-dpll.patch b/1117-dpll-allow-registering-fw-identified-pin-with-a-different-dpll.patch new file mode 100644 index 000000000..51852e8f0 --- /dev/null +++ b/1117-dpll-allow-registering-fw-identified-pin-with-a-different-dpll.patch @@ -0,0 +1,125 @@ +From 0da69a253f03f7e520706958f17747f6c7599ce4 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:06 +0200 +Subject: [PATCH] dpll: allow registering FW-identified pin with a different + DPLL + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit c191b319f20873cd62320cf738a53875827cd89d +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:34 2026 +0200 + + dpll: allow registering FW-identified pin with a different DPLL + + Relax the (module, clock_id) equality requirement when registering a + pin identified by firmware (pin->fwnode). Some platforms associate a + FW-described pin with a DPLL instance that differs from the pin's + (module, clock_id) tuple. For such pins, permit registration without + requiring the strict match. Non-FW pins still require equality. + + Keep netlink pin module reporting/filtering safe for this relaxed + registration model by caching the module name in the pin object at + allocation time and using the cached string in netlink paths. + This avoids dereferencing pin->module after provider module teardown. + + Reviewed-by: Jiri Pirko + Reviewed-by: Arkadiusz Kubalewski + Reviewed-by: Aleksandr Loktionov + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-3-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index f1b76fc..758363b 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -652,6 +653,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, + pin->pin_idx = pin_idx; + pin->clock_id = clock_id; + pin->module = module; ++ strscpy(pin->module_name, module_name(module)); + if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX || + prop->type > DPLL_PIN_TYPE_MAX)) { + ret = -EINVAL; +@@ -884,11 +886,21 @@ dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, + return -EINVAL; + + mutex_lock(&dpll_lock); +- if (WARN_ON(!(dpll->module == pin->module && +- dpll->clock_id == pin->clock_id))) ++ ++ /* ++ * For pins identified via firmware (pin->fwnode), allow registration ++ * even if the pin's (module, clock_id) differs from the target DPLL. ++ * For non-fwnode pins, require a strict (module, clock_id) match. ++ */ ++ if (!pin->fwnode && ++ WARN_ON_ONCE(dpll->module != pin->module || ++ dpll->clock_id != pin->clock_id)) { + ret = -EINVAL; +- else +- ret = __dpll_pin_register(dpll, pin, ops, priv, NULL); ++ goto out_unlock; ++ } ++ ++ ret = __dpll_pin_register(dpll, pin, ops, priv, NULL); ++out_unlock: + mutex_unlock(&dpll_lock); + + return ret; +diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h +index 0d861bd..fcc1564 100644 +--- a/drivers/dpll/dpll_core.h ++++ b/drivers/dpll/dpll_core.h +@@ -50,6 +50,7 @@ struct dpll_device { + * @pin_idx: index of a pin given by dev driver + * @clock_id: clock_id of creator + * @module: module of creator ++ * @module_name: module name of creator + * @fwnode: optional reference to firmware node + * @dpll_refs: hold referencees to dplls pin was registered with + * @parent_refs: hold references to parent pins pin was registered with +@@ -77,6 +78,7 @@ struct dpll_pin { + refcount_t refcount; + struct ref_tracker_dir refcnt_tracker; + struct rcu_head rcu; ++ RH_KABI_EXTEND(char module_name[MODULE_NAME_LEN]) + }; + + /** +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index 7a86b86..bdd3637 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -712,7 +712,7 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin, + if (ret) + return ret; + if (nla_put_string(msg, DPLL_A_PIN_MODULE_NAME, +- module_name(pin->module))) ++ pin->module_name)) + return -EMSGSIZE; + if (nla_put_64bit(msg, DPLL_A_PIN_CLOCK_ID, sizeof(pin->clock_id), + &pin->clock_id, DPLL_A_PIN_PAD)) +@@ -1659,9 +1659,9 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr, + xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) { + prop = &pin->prop; + cid_match = clock_id ? pin->clock_id == clock_id : true; +- mod_match = mod_name_attr && module_name(pin->module) ? ++ mod_match = mod_name_attr && pin->module_name[0] ? + !nla_strcmp(mod_name_attr, +- module_name(pin->module)) : true; ++ pin->module_name) : true; + type_match = type ? prop->type == type : true; + board_match = board_label ? (prop->board_label ? + !nla_strcmp(board_label, prop->board_label) : false) : diff --git a/1118-dpll-fix-stale-iteration-in-dpll-pin-on-pin-unregister.patch b/1118-dpll-fix-stale-iteration-in-dpll-pin-on-pin-unregister.patch new file mode 100644 index 000000000..51c3b4f6a --- /dev/null +++ b/1118-dpll-fix-stale-iteration-in-dpll-pin-on-pin-unregister.patch @@ -0,0 +1,61 @@ +From a376b1535cd2325c1c35d61d69036164bd1fa5a6 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:09 +0200 +Subject: [PATCH] dpll: fix stale iteration in dpll_pin_on_pin_unregister() + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 32239d600236a986c8e6d16aa814d3d91066b244 +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:35 2026 +0200 + + dpll: fix stale iteration in dpll_pin_on_pin_unregister() + + Neither parent->dpll_refs nor pin->dpll_refs on its own is a correct + iteration target at unregister time: + + - pin->dpll_refs includes DPLLs the child was registered against + via a different parent or directly; blind unregister WARNs on + the cookie miss in dpll_xa_ref_pin_del(). + - parent->dpll_refs reflects the parent's current attachments, not + those at child-register time. Another driver may have (un)reg'd + the parent against additional DPLLs in the meantime, so we miss + registrations that exist and visit DPLLs that have none. + + Walk pin->dpll_refs and use dpll_pin_registration_find() to filter + to entries whose cookie is this parent. Symmetric with + dpll_pin_on_pin_register(), correct under any subsequent change to + parent->dpll_refs. + + Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions") + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-4-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 758363b..3d23ad1 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -1031,14 +1031,19 @@ EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register); + void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv) + { ++ struct dpll_pin_registration *reg; + struct dpll_pin_ref *ref; + unsigned long i; + + mutex_lock(&dpll_lock); + dpll_pin_delete_ntf(pin); + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); +- xa_for_each(&pin->dpll_refs, i, ref) ++ xa_for_each(&pin->dpll_refs, i, ref) { ++ reg = dpll_pin_registration_find(ref, ops, priv, parent); ++ if (!reg) ++ continue; + __dpll_pin_unregister(ref->dpll, pin, ops, priv, parent); ++ } + mutex_unlock(&dpll_lock); + } + EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); diff --git a/1119-dpll-send-delete-notification-before-unregister-in-on-pin-rollback.patch b/1119-dpll-send-delete-notification-before-unregister-in-on-pin-rollback.patch new file mode 100644 index 000000000..51d0f947f --- /dev/null +++ b/1119-dpll-send-delete-notification-before-unregister-in-on-pin-rollback.patch @@ -0,0 +1,47 @@ +From a3f64b573a45ee715a3833a0034adc0b8f9d9813 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:13 +0200 +Subject: [PATCH] dpll: send delete notification before unregister in on-pin + rollback + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit e83b403eb142be18d223fc599c0ac45519053671 +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:36 2026 +0200 + + dpll: send delete notification before unregister in on-pin rollback + + The rollback path in dpll_pin_on_pin_register() called + __dpll_pin_unregister() before dpll_pin_delete_ntf(). When the + unregister dropped the pin's last DPLL reference it cleared the + DPLL_REGISTERED mark in dpll_pin_xa, so the subsequent + dpll_pin_event_send() failed dpll_pin_available() and aborted with + -ENODEV. As a result userspace was never notified of the rollback + deletion and remained out of sync with the kernel. + + Send the delete notification first, matching the order used by + dpll_pin_unregister() and dpll_pin_on_pin_unregister(). + + Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions") + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-5-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 3d23ad1..c85cc00 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -1007,9 +1007,9 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, + dpll_unregister: + xa_for_each(&parent->dpll_refs, i, ref) + if (i < stop) { ++ dpll_pin_delete_ntf(pin); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, + parent); +- dpll_pin_delete_ntf(pin); + } + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); + unlock: diff --git a/1120-dpll-emit-per-dpll-delete-notifications-in-dpll-pin-on-pin-unregister.patch b/1120-dpll-emit-per-dpll-delete-notifications-in-dpll-pin-on-pin-unregister.patch new file mode 100644 index 000000000..82fcb6094 --- /dev/null +++ b/1120-dpll-emit-per-dpll-delete-notifications-in-dpll-pin-on-pin-unregister.patch @@ -0,0 +1,53 @@ +From bed06b47d17a43e01769d54ed1f97ff04618ae3d Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:18 +0200 +Subject: [PATCH] dpll: emit per-dpll delete notifications in + dpll_pin_on_pin_unregister() + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit df0ba51ccf873e533669578104981109217d8201 +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:37 2026 +0200 + + dpll: emit per-dpll delete notifications in dpll_pin_on_pin_unregister() + + dpll_pin_on_pin_register() emits a creation notification for every + parent->dpll_refs entry, but dpll_pin_on_pin_unregister() emitted only + one deletion notification outside the loop. When a pin is registered + against multiple parent dplls, userspace sees N creates but a single + delete and leaks per-dpll state. + + Move dpll_pin_delete_ntf() into the loop and call it before + __dpll_pin_unregister() so the DPLL_REGISTERED mark is still set when + dpll_pin_available() is consulted. + + Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions") + Signed-off-by: Grzegorz Nitka + Reviewed-by: Arkadiusz Kubalewski + Link: https://patch.msgid.link/20260607183045.1213735-6-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index c85cc00..60171c9 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -1036,14 +1036,14 @@ void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + unsigned long i; + + mutex_lock(&dpll_lock); +- dpll_pin_delete_ntf(pin); +- dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); + xa_for_each(&pin->dpll_refs, i, ref) { + reg = dpll_pin_registration_find(ref, ops, priv, parent); + if (!reg) + continue; ++ dpll_pin_delete_ntf(pin); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, parent); + } ++ dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); + mutex_unlock(&dpll_lock); + } + EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister); diff --git a/1121-dpll-guard-sync-pair-removal-on-full-pin-unregister.patch b/1121-dpll-guard-sync-pair-removal-on-full-pin-unregister.patch new file mode 100644 index 000000000..4b4bfa31e --- /dev/null +++ b/1121-dpll-guard-sync-pair-removal-on-full-pin-unregister.patch @@ -0,0 +1,50 @@ +From f9973a3184eda6eeb322dde368d07a2fc5860b81 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:21 +0200 +Subject: [PATCH] dpll: guard sync-pair removal on full pin unregister + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 0a5c720a7d57d2287d5566c4ad93ee26b7c06845 +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:38 2026 +0200 + + dpll: guard sync-pair removal on full pin unregister + + __dpll_pin_unregister() wiped the global sync-pair state on every + (dpll, ops, priv, cookie) tuple removed from a pin. When a pin is + registered multiple times and only one registration is being torn + down, this dropped sync-pair pairings still in use by the surviving + registrations. + + Move dpll_pin_ref_sync_pair_del() inside the xa_empty(&pin->dpll_refs) + branch so it only runs when the last registration is gone, alongside + clearing the DPLL_REGISTERED mark. + + Fixes: 58256a26bfb3 ("dpll: add reference sync get/set") + Signed-off-by: Grzegorz Nitka + Reviewed-by: Arkadiusz Kubalewski + Link: https://patch.msgid.link/20260607183045.1213735-7-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 60171c9..8f4ebf7 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -926,11 +926,12 @@ __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv, void *cookie) + { + ASSERT_DPLL_PIN_REGISTERED(pin); +- dpll_pin_ref_sync_pair_del(pin->id); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); + dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie); +- if (xa_empty(&pin->dpll_refs)) ++ if (xa_empty(&pin->dpll_refs)) { ++ dpll_pin_ref_sync_pair_del(pin->id); + xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); ++ } + } + + /** diff --git a/1122-dpll-balance-create-delete-notifications-in-dpll-pin-un-register.patch b/1122-dpll-balance-create-delete-notifications-in-dpll-pin-un-register.patch new file mode 100644 index 000000000..aa52a0f34 --- /dev/null +++ b/1122-dpll-balance-create-delete-notifications-in-dpll-pin-un-register.patch @@ -0,0 +1,50 @@ +From cb38fe491e0afb090c3e20481b06b859ae3ae969 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:24 +0200 +Subject: [PATCH] dpll: balance create/delete notifications in + __dpll_pin_(un)register + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 1a2292101c0dc422466c673031de03d2e871adbe +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:39 2026 +0200 + + dpll: balance create/delete notifications in __dpll_pin_(un)register + + __dpll_pin_register() emits dpll_pin_create_ntf() internally, but + __dpll_pin_unregister() left the matching delete to its callers. The + counts then diverge on dpll_pin_on_pin_register() rollback and on + dpll_pin_on_pin_unregister(), leaking stale notifications. + + Emit dpll_pin_delete_ntf() inside __dpll_pin_unregister() and drop the + now-redundant call in dpll_pin_unregister(). + + Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions") + Signed-off-by: Grzegorz Nitka + Reviewed-by: Arkadiusz Kubalewski + Link: https://patch.msgid.link/20260607183045.1213735-8-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 8f4ebf7..6020810 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -926,6 +926,7 @@ __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv, void *cookie) + { + ASSERT_DPLL_PIN_REGISTERED(pin); ++ dpll_pin_delete_ntf(pin); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); + dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie); + if (xa_empty(&pin->dpll_refs)) { +@@ -953,7 +954,6 @@ void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + return; + + mutex_lock(&dpll_lock); +- dpll_pin_delete_ntf(pin); + __dpll_pin_unregister(dpll, pin, ops, priv, NULL); + mutex_unlock(&dpll_lock); + } diff --git a/1123-dpll-extend-pin-notifier-with-notification-source-id.patch b/1123-dpll-extend-pin-notifier-with-notification-source-id.patch new file mode 100644 index 000000000..c832141ce --- /dev/null +++ b/1123-dpll-extend-pin-notifier-with-notification-source-id.patch @@ -0,0 +1,186 @@ +From 74b646def907e81b6d4ffdd13873c37ba3c88db9 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:27 +0200 +Subject: [PATCH] dpll: extend pin notifier with notification source ID + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 0bf47f722fa9e4ecdab7497afc1af64330540bed +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:40 2026 +0200 + + dpll: extend pin notifier with notification source ID + + Extend the DPLL pin notification API to include a source identifier + indicating where the notification originates. This allows notifier + consumers to distinguish between notifications coming from + an associated DPLL instance, a parent pin, or the pin itself. + + A new field, src_clock_id, is added to struct dpll_pin_notifier_info + and is passed through all pin-related notification paths. Callers of + dpll_pin_notify() are updated to provide a meaningful source identifier + based on their context: + - pin registration/unregistration uses the DPLL's clock_id, + - pin-on-pin operations use the parent pin's clock_id, + - pin changes use the pin's own clock_id. + + As introduced in the commit ("dpll: allow registering FW-identified pin + with a different DPLL"), it is possible to share the same physical pin + via firmware description (fwnode) with DPLL objects from different + kernel modules. This means that a given pin can be registered multiple + times. + + Driver such as ICE (E825 devices) rely on this mechanism when listening + for the event where a shared-fwnode pin appears, while avoiding reacting + to events triggered by their own registration logic. + + This change only extends the notification metadata and does not alter + existing semantics for drivers that do not use the new field. + + Reviewed-by: Arkadiusz Kubalewski + Reviewed-by: Aleksandr Loktionov + Reviewed-by: Jiri Pirko + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-9-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c +index 6020810..2c57527 100644 +--- a/drivers/dpll/dpll_core.c ++++ b/drivers/dpll/dpll_core.c +@@ -72,7 +72,8 @@ void dpll_device_notify(struct dpll_device *dpll, unsigned long action) + call_dpll_notifiers(action, &info); + } + +-void dpll_pin_notify(struct dpll_pin *pin, unsigned long action) ++void dpll_pin_notify(struct dpll_pin *pin, u64 src_clock_id, ++ unsigned long action) + { + struct dpll_pin_notifier_info info = { + .pin = pin, +@@ -81,6 +82,7 @@ void dpll_pin_notify(struct dpll_pin *pin, unsigned long action) + .clock_id = pin->clock_id, + .fwnode = pin->fwnode, + .prop = &pin->prop, ++ .src_clock_id = src_clock_id, + }; + + call_dpll_notifiers(action, &info); +@@ -849,7 +851,7 @@ __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin, + if (ret) + goto ref_pin_del; + xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED); +- dpll_pin_create_ntf(pin); ++ dpll_pin_create_ntf(pin, dpll->clock_id); + + return ret; + +@@ -926,7 +928,7 @@ __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin, + const struct dpll_pin_ops *ops, void *priv, void *cookie) + { + ASSERT_DPLL_PIN_REGISTERED(pin); +- dpll_pin_delete_ntf(pin); ++ dpll_pin_delete_ntf(pin, dpll->clock_id); + dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie); + dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie); + if (xa_empty(&pin->dpll_refs)) { +@@ -999,7 +1001,7 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, + stop = i; + goto dpll_unregister; + } +- dpll_pin_create_ntf(pin); ++ dpll_pin_create_ntf(pin, parent->clock_id); + } + mutex_unlock(&dpll_lock); + +@@ -1008,7 +1010,7 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin, + dpll_unregister: + xa_for_each(&parent->dpll_refs, i, ref) + if (i < stop) { +- dpll_pin_delete_ntf(pin); ++ dpll_pin_delete_ntf(pin, parent->clock_id); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, + parent); + } +@@ -1041,7 +1043,7 @@ void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin, + reg = dpll_pin_registration_find(ref, ops, priv, parent); + if (!reg) + continue; +- dpll_pin_delete_ntf(pin); ++ dpll_pin_delete_ntf(pin, parent->clock_id); + __dpll_pin_unregister(ref->dpll, pin, ops, priv, parent); + } + dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin); +diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h +index fcc1564..e4bb4b2 100644 +--- a/drivers/dpll/dpll_core.h ++++ b/drivers/dpll/dpll_core.h +@@ -110,6 +110,7 @@ extern struct xarray dpll_pin_xa; + extern struct mutex dpll_lock; + + void dpll_device_notify(struct dpll_device *dpll, unsigned long action); +-void dpll_pin_notify(struct dpll_pin *pin, unsigned long action); ++void dpll_pin_notify(struct dpll_pin *pin, u64 src_clock_id, ++ unsigned long action); + + #endif +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index bdd3637..0428da3 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -924,15 +924,15 @@ dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin) + return ret; + } + +-int dpll_pin_create_ntf(struct dpll_pin *pin) ++int dpll_pin_create_ntf(struct dpll_pin *pin, u64 src_clock_id) + { +- dpll_pin_notify(pin, DPLL_PIN_CREATED); ++ dpll_pin_notify(pin, src_clock_id, DPLL_PIN_CREATED); + return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin); + } + +-int dpll_pin_delete_ntf(struct dpll_pin *pin) ++int dpll_pin_delete_ntf(struct dpll_pin *pin, u64 src_clock_id) + { +- dpll_pin_notify(pin, DPLL_PIN_DELETED); ++ dpll_pin_notify(pin, src_clock_id, DPLL_PIN_DELETED); + return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); + } + +@@ -947,7 +947,7 @@ int dpll_pin_delete_ntf(struct dpll_pin *pin) + int __dpll_pin_change_ntf(struct dpll_pin *pin) + { + lockdep_assert_held(&dpll_lock); +- dpll_pin_notify(pin, DPLL_PIN_CHANGED); ++ dpll_pin_notify(pin, pin->clock_id, DPLL_PIN_CHANGED); + return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); + } + EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf); +diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h +index a9cfd55..4f63aa5 100644 +--- a/drivers/dpll/dpll_netlink.h ++++ b/drivers/dpll/dpll_netlink.h +@@ -8,6 +8,6 @@ int dpll_device_create_ntf(struct dpll_device *dpll); + + int dpll_device_delete_ntf(struct dpll_device *dpll); + +-int dpll_pin_create_ntf(struct dpll_pin *pin); ++int dpll_pin_create_ntf(struct dpll_pin *pin, u64 src_clock_id); + +-int dpll_pin_delete_ntf(struct dpll_pin *pin); ++int dpll_pin_delete_ntf(struct dpll_pin *pin, u64 src_clock_id); +diff --git a/include/linux/dpll.h b/include/linux/dpll.h +index 5ee402f..6117120 100644 +--- a/include/linux/dpll.h ++++ b/include/linux/dpll.h +@@ -265,6 +265,7 @@ struct dpll_pin_notifier_info { + u64 clock_id; + const struct fwnode_handle *fwnode; + const struct dpll_pin_properties *prop; ++ u64 src_clock_id; + }; + + #if IS_ENABLED(CONFIG_DPLL) diff --git a/1124-dpll-allow-fwnode-pins-to-attempt-state-change-without-capability-bit.patch b/1124-dpll-allow-fwnode-pins-to-attempt-state-change-without-capability-bit.patch new file mode 100644 index 000000000..e13b6925d --- /dev/null +++ b/1124-dpll-allow-fwnode-pins-to-attempt-state-change-without-capability-bit.patch @@ -0,0 +1,66 @@ +From 5bbe55502a03aeea3e38b0fe23ddae7cf0822f69 Mon Sep 17 00:00:00 2001 +From: Michal Schmidt +Date: Mon, 22 Jun 2026 17:14:31 +0200 +Subject: [PATCH] dpll: allow fwnode pins to attempt state change without + capability bit + +JIRA: https://redhat.atlassian.net/browse/RHEL-186631 + +commit 521b6d5de08d506f0e3e1bf0a9b14766140107fc +Author: Grzegorz Nitka +Date: Sun Jun 7 20:30:41 2026 +0200 + + dpll: allow fwnode pins to attempt state change without capability bit + + Pins registered with an fwnode may have .state_on_dpll_set implemented + without advertising DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE upfront. + Requiring the bit for fwnode pins ties firmware description to driver + implementation details unnecessarily. + + Relax the capability check in dpll_pin_state_set() and + dpll_pin_on_pin_state_set(): when a pin has an associated fwnode, bypass + the capability gate and let the ops layer decide, returning -EOPNOTSUPP + if .state_on_dpll_set is absent. Non-fwnode pins retain the original + strict behavior. + + This is used later in the series by the SyncE_Ref output pin, which + relies on the fwnode path for state control. + + Reviewed-by: Aleksandr Loktionov + Reviewed-by: Jiri Pirko + Signed-off-by: Grzegorz Nitka + Link: https://patch.msgid.link/20260607183045.1213735-10-grzegorz.nitka@intel.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: Michal Schmidt + +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index 0428da3..aa77d25 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -1334,8 +1334,11 @@ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx, + unsigned long i; + int ret; + ++ /* fwnode pins may not set the capability bit upfront; let the ops ++ * layer return -EOPNOTSUPP if the operation is unsupported. ++ */ + if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & +- pin->prop.capabilities)) { ++ pin->prop.capabilities) && !pin->fwnode) { + NL_SET_ERR_MSG(extack, "state changing is not allowed"); + return -EOPNOTSUPP; + } +@@ -1370,8 +1373,11 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin, + struct dpll_pin_ref *ref; + int ret; + ++ /* fwnode pins may not set the capability bit upfront; let the ops ++ * layer return -EOPNOTSUPP if the operation is unsupported. ++ */ + if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE & +- pin->prop.capabilities)) { ++ pin->prop.capabilities) && !pin->fwnode) { + NL_SET_ERR_MSG(extack, "state changing is not allowed"); + return -EOPNOTSUPP; + } diff --git a/2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch b/2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch new file mode 100644 index 000000000..0c5c7ed61 --- /dev/null +++ b/2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch @@ -0,0 +1,97 @@ +From 884d1cab4bfadf53f05ca36f35f06d3cc1f916a2 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Tue, 4 Aug 2026 10:08:07 +0000 +Subject: [PATCH] KVM: x86: Check for invalid/obsolete root *after* making MMU + pages available + +JIRA: https://redhat.atlassian.net/browse/RHEL-224013 +CVE: CVE-2026-64561 +Backported from tree(s): linux + +KVM: x86: Check for invalid/obsolete root *after* making MMU pages available + +Check for a "stale" page fault, i.e. for an invalid and/or obsolete root, +after making MMU pages available for the shadow MMU. If reclaiming shadow +pages zaps an in-use root, i.e. marks it invalid, then KVM will attempt to +map memory into an invalid root. On its own, populating an invalid root is +"fine", but because child shadow pages inherit their parent's role, any +children created during the map/fetch will be created as invalid pages, +thus violating KVM's invariant that invalid pages are never on the list of +active MMU pages. + +Note, the underlying flaw has existed since KVM first started tracking +invalid roots in 2008 (commit 2e53d63acba7, "KVM: MMU: ignore zapped root +pagetables"), but the true badness only came along in 2020 (Linux 5.9) +with the invariant that invalid shadow pages can't be on the list of +active pages. + +Note #2, inheriting role.invalid when creating child shadow pages is also +far from ideal; that flaw will be addressed separately. + +Reported-by: Hyunwoo Kim +Fixes: f95eec9bed76 ("KVM: x86/mmu: Don't put invalid SPs back on the list of active pages") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +(cherry picked from commit 2abd5287f08319fa35764566b15c6e22cb1068db) +Signed-off-by: CKI Backport Bot +--- + arch/x86/kvm/mmu/mmu.c | 9 +++++---- + arch/x86/kvm/mmu/paging_tmpl.h | 10 ++++++---- + 2 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index ab4bbb692064..0c4553e57731 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4814,16 +4814,17 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault + if (r != RET_PF_CONTINUE) + return r; + +- r = RET_PF_RETRY; + write_lock(&vcpu->kvm->mmu_lock); + +- if (is_page_fault_stale(vcpu, fault)) +- goto out_unlock; +- + r = make_mmu_pages_available(vcpu); + if (r) + goto out_unlock; + ++ if (is_page_fault_stale(vcpu, fault)) { ++ r = RET_PF_RETRY; ++ goto out_unlock; ++ } ++ + r = direct_map(vcpu, fault); + + out_unlock: +diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h +index 901cd2bd40b8..6465de820e70 100644 +--- a/arch/x86/kvm/mmu/paging_tmpl.h ++++ b/arch/x86/kvm/mmu/paging_tmpl.h +@@ -827,15 +827,17 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault + } + #endif + +- r = RET_PF_RETRY; + write_lock(&vcpu->kvm->mmu_lock); + +- if (is_page_fault_stale(vcpu, fault)) +- goto out_unlock; +- + r = make_mmu_pages_available(vcpu); + if (r) + goto out_unlock; ++ ++ if (is_page_fault_stale(vcpu, fault)) { ++ r = RET_PF_RETRY; ++ goto out_unlock; ++ } ++ + r = FNAME(fetch)(vcpu, fault, &walker); + + out_unlock: +-- +GitLab + diff --git a/Makefile.rhelver b/Makefile.rhelver index 03c8283a4..095e4b704 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 2 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 211.42.1 +RHEL_RELEASE = 211.43.1 # # RHEL_REBASE_NUM diff --git a/kernel.changelog b/kernel.changelog index d898c6934..ec783ecd5 100644 --- a/kernel.changelog +++ b/kernel.changelog @@ -1,3 +1,32 @@ +* Mon Aug 03 2026 CKI KWF Bot [6.12.0-211.43.1.el10_2] +- redhat/kernel.spec: make module and modules-core provides use variant (Jan Stancek) [RHEL-213965] +- dpll: allow fwnode pins to attempt state change without capability bit (Jakub Ramaseuski) [RHEL-211011] +- dpll: extend pin notifier with notification source ID (Jakub Ramaseuski) [RHEL-211011] +- dpll: balance create/delete notifications in __dpll_pin_(un)register (Jakub Ramaseuski) [RHEL-211011] +- dpll: guard sync-pair removal on full pin unregister (Jakub Ramaseuski) [RHEL-211011] +- dpll: emit per-dpll delete notifications in dpll_pin_on_pin_unregister() (Jakub Ramaseuski) [RHEL-211011] +- dpll: send delete notification before unregister in on-pin rollback (Jakub Ramaseuski) [RHEL-211011] +- dpll: fix stale iteration in dpll_pin_on_pin_unregister() (Jakub Ramaseuski) [RHEL-211011] +- dpll: allow registering FW-identified pin with a different DPLL (Jakub Ramaseuski) [RHEL-211011] +- dpll: add generic DPLL type (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: make frequency monitor a per-device attribute (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work (Jakub Ramaseuski) [RHEL-211011] +- dpll: export __dpll_device_change_ntf() for use under dpll_lock (Jakub Ramaseuski) [RHEL-211011] +- dpll: change dpll_netdev_pin_handle_size() to assume DPLL_A_PIN_ID will be used (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: fix memory leak on pin registration failure (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: Use named initializers for struct i2c_device_id (Jakub Ramaseuski) [RHEL-211011] +- dpll: Prevent duplicate registrations (Jakub Ramaseuski) [RHEL-211011] +- dpll: export __dpll_pin_change_ntf() for use under dpll_lock (Jakub Ramaseuski) [RHEL-211011] +- drm/i915/psr: Use DC_OFF wake reference to block DC6 on vblank enable (Anusha Srivatsa) [RHEL-172832] +- drm/i915/psr: Block DC states on vblank enable when Panel Replay supported (Anusha Srivatsa) [RHEL-172832] +- drm/i915/psr: Don't enable Panel Replay on sink if globally disabled (Anusha Srivatsa) [RHEL-172832] +- drm/i915/alpm: ALPM disable fixes (Anusha Srivatsa) [RHEL-172832] +- procfs: fix possible double mmput() in do_procmap_query() (Rafael Aquini) [RHEL-189665] {CVE-2026-23199} +- procfs: avoid fetching build ID while holding VMA lock (Rafael Aquini) [RHEL-189665] {CVE-2026-23199} +- timers: Fix NULL function pointer race in timer_shutdown_sync() (CKI Backport Bot) [RHEL-189563] {CVE-2025-68214} +- net: wwan: t7xx: Add delay between MD and SAP suspend (CKI Backport Bot) [RHEL-184266] +Resolves: RHEL-172832, RHEL-184266, RHEL-189563, RHEL-189665, RHEL-211011, RHEL-213965 + * Wed Jul 29 2026 CKI KWF Bot [6.12.0-211.42.1.el10_2] - net/sched: cls_api: Handle TC_ACT_CONSUMED in tcf_qevent_handle (CKI Backport Bot) [RHEL-214082] {CVE-2026-64530} - ksm: use range-walk function to jump over holes in scan_get_next_rmap_item (Rafael Aquini) [RHEL-189554] {CVE-2025-68211} diff --git a/kernel.spec b/kernel.spec index 949904afc..3299a0da2 100644 --- a/kernel.spec +++ b/kernel.spec @@ -176,13 +176,13 @@ Summary: The Linux kernel %define specrpmversion 6.12.0 %define specversion 6.12.0 %define patchversion 6.12 -%define pkgrelease 211.42.1 +%define pkgrelease 211.43.1 %define kversion 6 %define tarfile_release 6.12.0-211.42.1.el10_2 # This is needed to do merge window version magic %define patchlevel 12 # This allows pkg_release to have configurable %%{?dist} tag -%define specrelease 211.42.1%{?buildid}%{?dist} +%define specrelease 211.43.1%{?buildid}%{?dist} # This defines the kabi tarball version %define kabiversion 6.12.0-211.42.1.el10_2 @@ -1128,6 +1128,33 @@ Patch1: patch-%{patchversion}-redhat.patch # empty final patch to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch +# Backports for 6.12.0-211.43.1.el10_2 +Patch1100: 1100-net-wwan-t7xx-add-delay-between-md-and-sap-suspend.patch +Patch1101: 1101-timers-fix-null-function-pointer-race-in-timer-shutdown-sync.patch +Patch1102: 1102-procfs-avoid-fetching-build-id-while-holding-vma-lock.patch +Patch1103: 1103-procfs-fix-possible-double-mmput-in-do-procmap-query.patch +Patch1104: 1104-drm-i915-alpm-alpm-disable-fixes.patch +Patch1105: 1105-drm-i915-psr-don-t-enable-panel-replay-on-sink-if-globally-disabled.patch +Patch1106: 1106-drm-i915-psr-block-dc-states-on-vblank-enable-when-panel-replay-supported.patch +Patch1107: 1107-drm-i915-psr-use-dc-off-wake-reference-to-block-dc6-on-vblank-enable.patch +Patch1108: 1108-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch +Patch1109: 1109-dpll-prevent-duplicate-registrations.patch +Patch1110: 1110-dpll-zl3073x-use-named-initializers-for-struct-i2c-device-id.patch +Patch1111: 1111-dpll-zl3073x-fix-memory-leak-on-pin-registration-failure.patch +Patch1112: 1112-dpll-change-dpll-netdev-pin-handle-size-to-assume-dpll-a-pin-id-will-be-used.patch +Patch1113: 1113-dpll-export-dpll-device-change-ntf-for-use-under-dpll-lock.patch +Patch1114: 1114-dpll-zl3073x-use-dpll-device-change-ntf-and-remove-change-work.patch +Patch1115: 1115-dpll-zl3073x-make-frequency-monitor-a-per-device-attribute.patch +Patch1116: 1116-dpll-add-generic-dpll-type.patch +Patch1117: 1117-dpll-allow-registering-fw-identified-pin-with-a-different-dpll.patch +Patch1118: 1118-dpll-fix-stale-iteration-in-dpll-pin-on-pin-unregister.patch +Patch1119: 1119-dpll-send-delete-notification-before-unregister-in-on-pin-rollback.patch +Patch1120: 1120-dpll-emit-per-dpll-delete-notifications-in-dpll-pin-on-pin-unregister.patch +Patch1121: 1121-dpll-guard-sync-pair-removal-on-full-pin-unregister.patch +Patch1122: 1122-dpll-balance-create-delete-notifications-in-dpll-pin-un-register.patch +Patch1123: 1123-dpll-extend-pin-notifier-with-notification-source-id.patch +Patch1124: 1124-dpll-allow-fwnode-pins-to-attempt-state-change-without-capability-bit.patch + # AlmaLinux Patch Patch2001: 0001-Enable-all-disabled-pci-devices-by-moving-to-unmaint.patch Patch2002: 0002-Bring-back-deprecated-pci-ids-to-mptsas-mptspi-drive.patch @@ -1140,6 +1167,7 @@ Patch2009: 0009-Bring-back-deprecated-pci-ids-to-mpt3sas-driver.patch Patch2010: 0001-Keep-fs-btrfs-files-in-modules-package.patch Patch2011: 2011-gve-Update-QPL-page-registration-logic.patch Patch2012: 2012-gve-Enable-reading-max-ring-size-in-DQO-QPL-mode.patch +Patch2013: 2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch # END OF PATCH DEFINITIONS @@ -1567,8 +1595,8 @@ This package provides less commonly used kernel modules for the %{?2:%{2} }kerne %package %{?1:%{1}-}modules\ Summary: kernel modules to match the %{?2:%{2}-}core kernel\ Provides: %{name}%{?1:-%{1}}-modules-%{_target_cpu} = %{specrpmversion}-%{release}\ -Provides: %{name}-modules-%{_target_cpu} = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ -Provides: %{name}-modules = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ +Provides: %{name}%{?1:-%{1}}-modules-%{_target_cpu} = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ +Provides: %{name}%{?1:-%{1}}-modules = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ Provides: installonlypkg(kernel-module)\ Provides: %{name}%{?1:-%{1}}-modules-uname-r = %{KVERREL}%{uname_suffix %{?1}}\ Requires: %{name}-uname-r = %{KVERREL}%{uname_suffix %{?1}}\ @@ -1590,8 +1618,8 @@ This package provides commonly used kernel modules for the %{?2:%{2}-}core kerne %package %{?1:%{1}-}modules-core\ Summary: Core kernel modules to match the %{?2:%{2}-}core kernel\ Provides: %{name}%{?1:-%{1}}-modules-core-%{_target_cpu} = %{specrpmversion}-%{release}\ -Provides: %{name}-modules-core-%{_target_cpu} = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ -Provides: %{name}-modules-core = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ +Provides: %{name}%{?1:-%{1}}-modules-core-%{_target_cpu} = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ +Provides: %{name}%{?1:-%{1}}-modules-core = %{specrpmversion}-%{release}%{uname_suffix %{?1}}\ Provides: installonlypkg(kernel-module)\ Provides: %{name}%{?1:-%{1}}-modules-core-uname-r = %{KVERREL}%{uname_suffix %{?1}}\ Requires: %{name}-uname-r = %{KVERREL}%{uname_suffix %{?1}}\ @@ -1990,6 +2018,33 @@ ApplyOptionalPatch patch-%{patchversion}-redhat.patch ApplyOptionalPatch linux-kernel-test.patch +# Applying backports for 6.12.0-211.43.1.el10_2 +ApplyPatch 1100-net-wwan-t7xx-add-delay-between-md-and-sap-suspend.patch +ApplyPatch 1101-timers-fix-null-function-pointer-race-in-timer-shutdown-sync.patch +ApplyPatch 1102-procfs-avoid-fetching-build-id-while-holding-vma-lock.patch +ApplyPatch 1103-procfs-fix-possible-double-mmput-in-do-procmap-query.patch +ApplyPatch 1104-drm-i915-alpm-alpm-disable-fixes.patch +ApplyPatch 1105-drm-i915-psr-don-t-enable-panel-replay-on-sink-if-globally-disabled.patch +ApplyPatch 1106-drm-i915-psr-block-dc-states-on-vblank-enable-when-panel-replay-supported.patch +ApplyPatch 1107-drm-i915-psr-use-dc-off-wake-reference-to-block-dc6-on-vblank-enable.patch +ApplyPatch 1108-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch +ApplyPatch 1109-dpll-prevent-duplicate-registrations.patch +ApplyPatch 1110-dpll-zl3073x-use-named-initializers-for-struct-i2c-device-id.patch +ApplyPatch 1111-dpll-zl3073x-fix-memory-leak-on-pin-registration-failure.patch +ApplyPatch 1112-dpll-change-dpll-netdev-pin-handle-size-to-assume-dpll-a-pin-id-will-be-used.patch +ApplyPatch 1113-dpll-export-dpll-device-change-ntf-for-use-under-dpll-lock.patch +ApplyPatch 1114-dpll-zl3073x-use-dpll-device-change-ntf-and-remove-change-work.patch +ApplyPatch 1115-dpll-zl3073x-make-frequency-monitor-a-per-device-attribute.patch +ApplyPatch 1116-dpll-add-generic-dpll-type.patch +ApplyPatch 1117-dpll-allow-registering-fw-identified-pin-with-a-different-dpll.patch +ApplyPatch 1118-dpll-fix-stale-iteration-in-dpll-pin-on-pin-unregister.patch +ApplyPatch 1119-dpll-send-delete-notification-before-unregister-in-on-pin-rollback.patch +ApplyPatch 1120-dpll-emit-per-dpll-delete-notifications-in-dpll-pin-on-pin-unregister.patch +ApplyPatch 1121-dpll-guard-sync-pair-removal-on-full-pin-unregister.patch +ApplyPatch 1122-dpll-balance-create-delete-notifications-in-dpll-pin-un-register.patch +ApplyPatch 1123-dpll-extend-pin-notifier-with-notification-source-id.patch +ApplyPatch 1124-dpll-allow-fwnode-pins-to-attempt-state-change-without-capability-bit.patch + # Applying AlmaLinux Patch ApplyPatch 0001-Enable-all-disabled-pci-devices-by-moving-to-unmaint.patch ApplyPatch 0002-Bring-back-deprecated-pci-ids-to-mptsas-mptspi-drive.patch @@ -2002,6 +2057,7 @@ ApplyPatch 0009-Bring-back-deprecated-pci-ids-to-mpt3sas-driver.patch ApplyPatch 0001-Keep-fs-btrfs-files-in-modules-package.patch ApplyPatch 2011-gve-Update-QPL-page-registration-logic.patch ApplyPatch 2012-gve-Enable-reading-max-ring-size-in-DQO-QPL-mode.patch +ApplyPatch 2013-CVE-2026-64561-KVM-x86-Check-for-invalid-obsolete-root.patch %{log_msg "End of patch applications"} # END OF PATCH APPLICATIONS @@ -4515,14 +4571,16 @@ fi\ # # %changelog -* Wed Aug 05 2026 Eduard Abdullin - 6.12.0-211.42.1 +* Thu Aug 06 2026 Eduard Abdullin - 6.12.0-211.43.1 - Debrand for AlmaLinux OS - Use AlmaLinux OS secure boot cert -* Wed Aug 05 2026 Neal Gompa - 6.12.0-211.42.1 +* Thu Aug 06 2026 Neal Gompa - 6.12.0-211.43.1 - Enable Btrfs support for all kernel variants -* Wed Aug 05 2026 Andrew Lukoshko - 6.12.0-211.42.1 +* Thu Aug 06 2026 Andrew Lukoshko - 6.12.0-211.43.1 +- KVM: x86: check for invalid/obsolete root after making MMU pages available + {CVE-2026-64561} - hpsa: bring back deprecated PCI ids #CFHack #CFHack2024 - mptsas: bring back deprecated PCI ids #CFHack #CFHack2024 - megaraid_sas: bring back deprecated PCI ids #CFHack #CFHack2024 @@ -4536,6 +4594,34 @@ fi\ - gve: enable reading max ring size from the device in DQO-QPL mode (backport from upstream) +* Mon Aug 03 2026 CKI KWF Bot [6.12.0-211.43.1.el10_2] +- redhat/kernel.spec: make module and modules-core provides use variant (Jan Stancek) [RHEL-213965] +- dpll: allow fwnode pins to attempt state change without capability bit (Jakub Ramaseuski) [RHEL-211011] +- dpll: extend pin notifier with notification source ID (Jakub Ramaseuski) [RHEL-211011] +- dpll: balance create/delete notifications in __dpll_pin_(un)register (Jakub Ramaseuski) [RHEL-211011] +- dpll: guard sync-pair removal on full pin unregister (Jakub Ramaseuski) [RHEL-211011] +- dpll: emit per-dpll delete notifications in dpll_pin_on_pin_unregister() (Jakub Ramaseuski) [RHEL-211011] +- dpll: send delete notification before unregister in on-pin rollback (Jakub Ramaseuski) [RHEL-211011] +- dpll: fix stale iteration in dpll_pin_on_pin_unregister() (Jakub Ramaseuski) [RHEL-211011] +- dpll: allow registering FW-identified pin with a different DPLL (Jakub Ramaseuski) [RHEL-211011] +- dpll: add generic DPLL type (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: make frequency monitor a per-device attribute (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: use __dpll_device_change_ntf() and remove change_work (Jakub Ramaseuski) [RHEL-211011] +- dpll: export __dpll_device_change_ntf() for use under dpll_lock (Jakub Ramaseuski) [RHEL-211011] +- dpll: change dpll_netdev_pin_handle_size() to assume DPLL_A_PIN_ID will be used (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: fix memory leak on pin registration failure (Jakub Ramaseuski) [RHEL-211011] +- dpll: zl3073x: Use named initializers for struct i2c_device_id (Jakub Ramaseuski) [RHEL-211011] +- dpll: Prevent duplicate registrations (Jakub Ramaseuski) [RHEL-211011] +- dpll: export __dpll_pin_change_ntf() for use under dpll_lock (Jakub Ramaseuski) [RHEL-211011] +- drm/i915/psr: Use DC_OFF wake reference to block DC6 on vblank enable (Anusha Srivatsa) [RHEL-172832] +- drm/i915/psr: Block DC states on vblank enable when Panel Replay supported (Anusha Srivatsa) [RHEL-172832] +- drm/i915/psr: Don't enable Panel Replay on sink if globally disabled (Anusha Srivatsa) [RHEL-172832] +- drm/i915/alpm: ALPM disable fixes (Anusha Srivatsa) [RHEL-172832] +- procfs: fix possible double mmput() in do_procmap_query() (Rafael Aquini) [RHEL-189665] {CVE-2026-23199} +- procfs: avoid fetching build ID while holding VMA lock (Rafael Aquini) [RHEL-189665] {CVE-2026-23199} +- timers: Fix NULL function pointer race in timer_shutdown_sync() (CKI Backport Bot) [RHEL-189563] {CVE-2025-68214} +- net: wwan: t7xx: Add delay between MD and SAP suspend (CKI Backport Bot) [RHEL-184266] + * Wed Jul 29 2026 CKI KWF Bot [6.12.0-211.42.1.el10_2] - net/sched: cls_api: Handle TC_ACT_CONSUMED in tcf_qevent_handle (CKI Backport Bot) [RHEL-214082] {CVE-2026-64530} - ksm: use range-walk function to jump over holes in scan_get_next_rmap_item (Rafael Aquini) [RHEL-189554] {CVE-2025-68211}