--- /dev/null
+From 4a5de2475370434b4d74c680145d3071f4621b5e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 20:38:51 +0200
+Subject: cpu: hotplug: Bound hotplug states sysfs output
+
+From: Bradley Morgan <include@grrlz.net>
+
+commit 86f436567f2516a0083b210bedc933544826a2c3 upstream.
+
+states_show() adds CPU hotplug state names into a single sysfs buffer
+using sprintf(). With enough registered states, this can write past the
+end of the PAGE_SIZE buffer.
+
+Use sysfs_emit_at() so output is bounded.
+
+Fixes: 98f8cdce1db5 ("cpu/hotplug: Add sysfs state interface")
+Signed-off-by: Bradley Morgan <include@grrlz.net>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260619163719.12103-2-include@grrlz.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cpu.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 08c2b2e30f23f1..69c7be3706f15b 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -2319,18 +2319,15 @@ static const struct attribute_group cpuhp_cpu_attr_group = {
+ static ssize_t show_cpuhp_states(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+- ssize_t cur, res = 0;
++ ssize_t res = 0;
+ int i;
+
+ mutex_lock(&cpuhp_state_mutex);
+ for (i = CPUHP_OFFLINE; i <= CPUHP_ONLINE; i++) {
+ struct cpuhp_step *sp = cpuhp_get_step(i);
+
+- if (sp->name) {
+- cur = sprintf(buf, "%3d: %s\n", i, sp->name);
+- buf += cur;
+- res += cur;
+- }
++ if (sp->name)
++ res += sysfs_emit_at(buf, res, "%3d: %s\n", i, sp->name);
+ }
+ mutex_unlock(&cpuhp_state_mutex);
+ return res;
+--
+2.53.0
+
--- /dev/null
+From 2d0256ad2a9abc32a8d058158523e32fce9b3653 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 08:41:53 +0900
+Subject: macsec: don't read an unset MAC header in macsec_encrypt()
+
+From: Daehyeon Ko <4ncienth@gmail.com>
+
+commit f5089008f90c0a7c5520dff3934e0af00adf322d upstream.
+
+macsec_encrypt() reads the Ethernet header via eth_hdr(skb)
+(skb->head + skb->mac_header) to memmove() the 12 source/destination MAC
+bytes forward and make room for the SecTAG.
+
+On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
+reaches the macsec ndo_start_xmit() with the MAC header unset, so
+eth_hdr(skb) resolves to skb->head + (u16)~0 and the read is out of
+bounds: a 12-byte heap over-read that is also emitted on the wire as the
+frame's outer source/destination MAC. KASAN reports a slab-out-of-bounds
+read in macsec_start_xmit() on 6.0; on current mainline a CONFIG_DEBUG_NET
+build flags it as an unset mac header in skb_mac_header().
+
+On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), added
+by commit 96cc4b69581d ("macvlan: do not assume mac_header is set in
+macvlan_broadcast()") for exactly this purpose.
+
+Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20260703083634.2035145-1-4ncienth@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index d19b5b1c1aca11..d07dba76940a9d 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -666,7 +666,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ }
+
+ unprotected_len = skb->len;
+- eth = eth_hdr(skb);
++ eth = skb_eth_hdr(skb);
+ sci_present = send_sci(secy);
+ hh = skb_push(skb, macsec_extra_len(sci_present));
+ memmove(hh, eth, 2 * ETH_ALEN);
+--
+2.53.0
+
nvmet-tcp-fix-potential-uaf-when-ddgst-mismatch.patch
+cpu-hotplug-bound-hotplug-states-sysfs-output.patch
+macsec-don-t-read-an-unset-mac-header-in-macsec_encr.patch
--- /dev/null
+From d8061ac076105b4a44a8c8e8327752017d8309e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 20:47:48 +0000
+Subject: futex: Prevent lockup in requeue-PI during signal/ timeout wakeup
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit bc7304f3ae20972d11db6e0b1b541c63feda5f05 ]
+
+During wait-requeue-pi (task A) and requeue-PI (task B) the following
+race can happen:
+
+ Task A Task B
+ futex_wait_requeue_pi()
+ futex_setup_timer()
+ futex_do_wait()
+ futex_requeue()
+ CLASS(hb, hb1)(&key1);
+ CLASS(hb, hb2)(&key2);
+ *timeout*
+ futex_requeue_pi_wakeup_sync()
+ requeue_state = Q_REQUEUE_PI_IGNORE
+
+ *blocks on hb->lock*
+
+ futex_proxy_trylock_atomic()
+ futex_requeue_pi_prepare()
+ Q_REQUEUE_PI_IGNORE => -EAGAIN
+ double_unlock_hb(hb1, hb2)
+ *retry*
+
+Task B acquires both hb locks and attempts to acquire the PI-lock of the
+top most waiter (task B). Task A is leaving early due to a signal/
+timeout and started removing itself from the queue. It updates its
+requeue_state but can not remove it from the list because this requires
+the hb lock which is owned by task B.
+
+Usually task A is able to swoop the lock after task B unlocked it.
+However if task B is of higher priority then task A may not be able to
+wake up in time and acquire the lock before task B gets it again.
+Especially on a UP system where A is never scheduled.
+
+As a result task A blocks on the lock and task B busy loops, trying to
+make progress but live locks the system instead. Tragic.
+
+This can be fixed by removing the top most waiter from the list in this
+case. This allows task B to grab the next top waiter (if any) in the
+next iteration and make progress.
+
+Remove the top most waiter if futex_requeue_pi_prepare() fails.
+Let the waiter conditionally remove itself from the list in
+handle_early_requeue_pi_wakeup().
+
+Fixes: 07d91ef510fb1 ("futex: Prevent requeue_pi() lock nesting issue on RT")
+Reported-by: Moritz Klammler <Moritz.Klammler@ferchau.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Link: https://patch.msgid.link/20260428103425.dywXyPd3@linutronix.de
+Closes: https://lore.kernel.org/all/VE1PR06MB6894BE61C173D802365BE19DFF4CA@VE1PR06MB6894.eurprd06.prod.outlook.com
+[cmllamas: adapt to 5.15, apply hunk to kernel/futex/core.c prior to the
+ requeue code split and use hb_waiters_dec() before the helper rename]
+Signed-off-by: Carlos Llamas <cmllamas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/futex/core.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/futex/core.c b/kernel/futex/core.c
+index 42cd8f2b6da813..8b4af13b8d262a 100644
+--- a/kernel/futex/core.c
++++ b/kernel/futex/core.c
+@@ -2078,8 +2078,11 @@ futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1,
+ return -EINVAL;
+
+ /* Ensure that this does not race against an early wakeup */
+- if (!futex_requeue_pi_prepare(top_waiter, NULL))
++ if (!futex_requeue_pi_prepare(top_waiter, NULL)) {
++ plist_del(&top_waiter->list, &hb1->chain);
++ hb_waiters_dec(hb1);
+ return -EAGAIN;
++ }
+
+ /*
+ * Try to take the lock for top_waiter and set the FUTEX_WAITERS bit
+@@ -3360,10 +3363,12 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
+
+ /*
+ * We were woken prior to requeue by a timeout or a signal.
+- * Unqueue the futex_q and determine which it was.
++ * Conditionally unqueue the futex_q and determine which it was.
+ */
+- plist_del(&q->list, &hb->chain);
+- hb_waiters_dec(hb);
++ if (!plist_node_empty(&q->list)) {
++ plist_del(&q->list, &hb->chain);
++ hb_waiters_dec(hb);
++ }
+
+ /* Handle spurious wakeups gracefully */
+ ret = -EWOULDBLOCK;
+--
+2.53.0
+
--- /dev/null
+From e1c95a05572050f1ffdcd33881131a04a3809995 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 08:40:44 +0900
+Subject: macsec: don't read an unset MAC header in macsec_encrypt()
+
+From: Daehyeon Ko <4ncienth@gmail.com>
+
+commit f5089008f90c0a7c5520dff3934e0af00adf322d upstream.
+
+macsec_encrypt() reads the Ethernet header via eth_hdr(skb)
+(skb->head + skb->mac_header) to memmove() the 12 source/destination MAC
+bytes forward and make room for the SecTAG.
+
+On the AF_PACKET SOCK_RAW + PACKET_QDISC_BYPASS transmit path the skb
+reaches the macsec ndo_start_xmit() with the MAC header unset, so
+eth_hdr(skb) resolves to skb->head + (u16)~0 and the read is out of
+bounds: a 12-byte heap over-read that is also emitted on the wire as the
+frame's outer source/destination MAC. KASAN reports a slab-out-of-bounds
+read in macsec_start_xmit() on 6.0; on current mainline a CONFIG_DEBUG_NET
+build flags it as an unset mac header in skb_mac_header().
+
+On the TX path the L2 header is at skb->data, so use skb_eth_hdr(), added
+by commit 96cc4b69581d ("macvlan: do not assume mac_header is set in
+macvlan_broadcast()") for exactly this purpose.
+
+Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20260703083634.2035145-1-4ncienth@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macsec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 9b0cb78507384b..5de940761ebf1e 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -662,7 +662,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ }
+
+ unprotected_len = skb->len;
+- eth = eth_hdr(skb);
++ eth = skb_eth_hdr(skb);
+ sci_present = send_sci(secy);
+ hh = skb_push(skb, macsec_extra_len(sci_present));
+ memmove(hh, eth, 2 * ETH_ALEN);
+--
+2.53.0
+
nvmet-tcp-fix-potential-uaf-when-ddgst-mismatch.patch
+futex-prevent-lockup-in-requeue-pi-during-signal-tim.patch
+macsec-don-t-read-an-unset-mac-header-in-macsec_encr.patch
--- /dev/null
+From 72289fce6d99033c398b3f0fb634511a5c80b39b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 00:27:09 +0000
+Subject: af_unix: Set gc_in_progress to true in unix_gc().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit d82ba05263c69fa2437fe93e4e561cc40f4c03af ]
+
+Igor Ushakov reported that unix_gc() could run with gc_in_progress
+being false if the work is scheduled while running:
+
+ Thread 1 Thread 2 Thread 3
+ -------- -------- --------
+ unix_schedule_gc() unix_schedule_gc()
+ `- if (!gc_in_progress) `- if (!gc_in_progress)
+ |- gc_in_progress = true |
+ `- queue_work() |
+ unix_gc() <----------------/ |
+ | |- gc_in_progress = true
+ ... `- queue_work()
+ | |
+ `- gc_in_progress = false |
+ |
+ unix_gc() <---------------------------------------------'
+ |
+ ... /* gc_in_progress == false */
+ |
+ `- gc_in_progress = false
+
+unix_peek_fpl() relies on gc_in_progress not to confuse GC
+by MSG_PEEK.
+
+Let's set gc_in_progress to true in unix_gc().
+
+Fixes: 8b90a9f819dc ("af_unix: Run GC on only one CPU.")
+Reported-by: Igor Ushakov <sysroot314@gmail.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260501073945.1884564-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Add setting gc_in_progress in __unix_gc(). Keep the existing
+ set in unix_gc() for wait_for_unix_gc() over-limit throttling. ]
+Signed-off-by: Igor Ushakov <sysroot314@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jay Wang <wanjay@amazon.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/garbage.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 66fd606c43f45d..38c8cae1316716 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -560,6 +560,8 @@ static void __unix_gc(struct work_struct *work)
+ struct sk_buff_head hitlist;
+ struct sk_buff *skb;
+
++ WRITE_ONCE(gc_in_progress, true);
++
+ spin_lock(&unix_gc_lock);
+
+ if (!unix_graph_maybe_cyclic) {
+--
+2.53.0
+
--- /dev/null
+From 54d42f00be1a39f947e46af6b913e28e17756e10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2026 15:39:00 +0530
+Subject: perf/x86/amd/brs: Fix kernel address leakage
+
+From: Sandipan Das <sandipan.das@amd.com>
+
+commit 47915e855fb38b42133e31ba917d99565f862154 upstream.
+
+A user-only branch stack can contain branches that originate from
+the kernel. As a result, kernel addresses are exposed to user space
+even when PERF_SAMPLE_BRANCH_USER is requested. On AMD processors
+supporting X86_FEATURE_BRS (Zen 3 only), perf can still report entries
+such as SYSRET/interrupt returns for which the branch-from addresses
+are in the kernel.
+
+E.g.
+
+ $ perf record -j any,u -c 4000 -e branch-brs -o - -- \
+ perf bench syscall basic --loop 1000 | \
+ perf script -i - -F brstack|tr ' ' '\n'| \
+ grep -E '0x[89a-f][0-9a-f]{15}'
+
+ ...
+ 0xffffffff810001c4/0x72e2e32955eb/-/-/-/0//-
+ 0xffffffff810001c4/0x72e2d94a9821/-/-/-/0//-
+ 0xffffffff810001c4/0x72e2d94ffa1b/-/-/-/0//-
+ ...
+
+BRS provides no hardware branch filtering, so privilege level
+filtering is performed entirely in software. However, amd_brs_match_plm()
+only validates the branch-to address against the requested privilege
+levels. For branches from the kernel to user space, the branch-from
+address is left unchecked and is leaked. Extend the software filter to
+also validate the branch-from address, so that any branch record whose
+branch-from address is in the kernel is dropped when
+PERF_SAMPLE_BRANCH_USER is requested.
+
+Fixes: 8910075d61a3 ("perf/x86/amd: Enable branch sampling priv level filtering")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: stable@vger.kernel.org
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Link: https://patch.msgid.link/f05931c4f89a146c364bd5dc6b8170b1ac611c65.1783701239.git.sandipan.das@amd.com
+Closes: https://lore.kernel.org/all/20260710110235.F3FD81F000E9@smtp.kernel.org/
+[sandipan: backport to linux-6.1.y]
+Signed-off-by: Sandipan Das <sandipan.das@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/events/amd/brs.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/x86/events/amd/brs.c b/arch/x86/events/amd/brs.c
+index f1bff153d94578..fd46e73cb8e716 100644
+--- a/arch/x86/events/amd/brs.c
++++ b/arch/x86/events/amd/brs.c
+@@ -262,13 +262,13 @@ void amd_brs_disable_all(void)
+ amd_brs_disable();
+ }
+
+-static bool amd_brs_match_plm(struct perf_event *event, u64 to)
++static bool amd_brs_match_plm(struct perf_event *event, u64 from, u64 to)
+ {
+ int type = event->attr.branch_sample_type;
+ int plm_k = PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV;
+ int plm_u = PERF_SAMPLE_BRANCH_USER;
+
+- if (!(type & plm_k) && kernel_ip(to))
++ if (!(type & plm_k) && (kernel_ip(to) || kernel_ip(from)))
+ return 0;
+
+ if (!(type & plm_u) && !kernel_ip(to))
+@@ -341,11 +341,11 @@ void amd_brs_drain(void)
+ */
+ to = (u64)(((s64)to << shift) >> shift);
+
+- if (!amd_brs_match_plm(event, to))
+- continue;
+-
+ rdmsrl(brs_from(brs_idx), from);
+
++ if (!amd_brs_match_plm(event, from, to))
++ continue;
++
+ perf_clear_branch_entry_bitfields(br+nr);
+
+ br[nr].from = from;
+--
+2.53.0
+
platform-x86-intel-uncore-freq-fix-current_freq_khz-.patch
+af_unix-set-gc_in_progress-to-true-in-unix_gc.patch
+perf-x86-amd-brs-fix-kernel-address-leakage.patch
--- /dev/null
+From f485839978a7381a4d7cbc551f827fdd7f32698d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:07 +0800
+Subject: bpf: Fix ld_{abs,ind} failure path analysis in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit ee861486e377edc55361c08dcbceab3f6b6577bd upstream.
+
+Usage of ld_{abs,ind} instructions got extended into subprogs some time
+ago via commit 09b28d76eac4 ("bpf: Add abnormal return checks."). These
+are only allowed in subprograms when the latter are BTF annotated and
+have scalar return types.
+
+The code generator in bpf_gen_ld_abs() has an abnormal exit path (r0=0 +
+exit) from legacy cBPF times. While the enforcement is on scalar return
+types, the verifier must also simulate the path of abnormal exit if the
+packet data load via ld_{abs,ind} failed.
+
+This is currently not the case. Fix it by having the verifier simulate
+both success and failure paths, and extend it in similar ways as we do
+for tail calls. The success path (r0=unknown, continue to next insn) is
+pushed onto stack for later validation and the r0=0 and return to the
+caller is done on the fall-through side.
+
+Fixes: 09b28d76eac4 ("bpf: Add abnormal return checks.")
+Reported-by: STAR Labs SG <info@starlabs.sg>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-2-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+[ Dropped visit_abnormal_return_insn changes: depends on 7.0 symbols from
+ e40f5a6bf88a ("bpf: correct stack liveness for tail calls");
+ Hunk1: adapted IS_ERR/PTR_ERR to !branch/-EFAULT to match push_stack()
+ NULL-on-failure convention. ]
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 7f1144486a8c4a..8c3c4ab989a053 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -16100,6 +16100,23 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ mark_reg_unknown(env, regs, BPF_REG_0);
+ /* ld_abs load up to 32-bit skb data. */
+ regs[BPF_REG_0].subreg_def = env->insn_idx + 1;
++ /*
++ * See bpf_gen_ld_abs() which emits a hidden BPF_EXIT with r0=0
++ * which must be explored by the verifier when in a subprog.
++ */
++ if (env->cur_state->curframe) {
++ struct bpf_verifier_state *branch;
++
++ mark_reg_scratched(env, BPF_REG_0);
++ branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
++ if (!branch)
++ return -EFAULT;
++ mark_reg_known_zero(env, regs, BPF_REG_0);
++ err = prepare_func_exit(env, &env->insn_idx);
++ if (err)
++ return err;
++ env->insn_idx--;
++ }
+ return 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f6e03317c14058ea9a9ea6805191794eb40df13d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 22:01:00 +0900
+Subject: drm/virtio: fix deadlock in display_info_cb by removing hotplug from
+ dequeue worker
+
+From: Ryosuke Yasuoka <ryasuoka@redhat.com>
+
+[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]
+
+A probe-time deadlock can occur between the dequeue worker and
+drm_client_register(). During probe, drm_client_register() holds
+clientlist_mutex and calls the fbdev hotplug callback, which triggers an
+atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
+waiting for virtqueue space. The dequeue worker that would free that
+space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
+drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
+to acquire the same clientlist_mutex. Since wake_up() is only called
+after the resp_cb loop, the probe thread is never woken and both threads
+deadlock.
+
+Fix this by removing the hotplug notification from
+virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info)
+is still updated synchronously in the callback.
+
+For the init path, drm_client_register() already fires an initial
+hotplug when the client is registered, which picks up the connector
+state updated by display_info_cb.
+
+For the runtime config_changed path, add a wait_event_timeout() in
+config_changed_work_func() so that display_info_cb updates the connector
+data before the hotplug notification is sent. Also replace
+drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since
+virtio-gpu never calls drm_kms_helper_poll_init() and thus
+drm_helper_hpd_irq_event() always returns false without doing anything.
+
+Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
+Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
+Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
+Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++-
+ drivers/gpu/drm/virtio/virtgpu_vq.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
+index 7dfb2006c561ca..ec31a41d33d678 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
+@@ -48,7 +48,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
+ virtio_gpu_cmd_get_edids(vgdev);
+ virtio_gpu_cmd_get_display_info(vgdev);
+ virtio_gpu_notify(vgdev);
+- drm_helper_hpd_irq_event(vgdev->ddev);
++ wait_event_timeout(vgdev->resp_wq,
++ !vgdev->display_info_pending,
++ 5 * HZ);
++ drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+ events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index 0d3d0d09f39b9f..bcc070b478d30e 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -669,9 +669,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
+ vgdev->display_info_pending = false;
+ spin_unlock(&vgdev->display_info_lock);
+ wake_up(&vgdev->resp_wq);
+-
+- if (!drm_helper_hpd_irq_event(vgdev->ddev))
+- drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+
+ static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
+--
+2.53.0
+
--- /dev/null
+From c40153ad06ebf9c980f59259f025b8bbdb5c0981 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 12:01:20 +0100
+Subject: fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+commit 04718f7c9290f95385f0dd328758753dc1c36dec upstream.
+
+Patch series "userfaultfd/pagemap: pre-existing fixes".
+
+These are pre-existing bug fixes that were carried at the front of the
+userfaultfd RWP working-set-tracking series up to v5 [1]. Per review
+feedback that fixes should not sit in the middle of a feature series, they
+are split out and sent on their own; the RWP series is reposted rebased on
+top of this.
+
+All six were flagged by the Sashiko AI review of the RWP series and carry
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>. They are
+independent of RWP, apply to mm-new directly, and carry Cc: stable@.
+
+ 1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in
+ make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates
+ when PAGEMAP_SCAN write-protects a hugetlb PTE.
+
+ 2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range
+ against HPAGE_SIZE rather than the hstate page size, so it never
+ write-protects gigantic hugetlb pages.
+
+ 3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an
+ unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole()
+ calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb
+ vma lock for read, and hugetlb_change_protection() then takes it
+ for write. Install the marker inline instead.
+
+ 4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp
+ on a device-private PMD permission downgrade, silently losing the
+ uffd-wp marker.
+
+ 5: userfaultfd: must_wait() applies pte_write() to a locklessly read
+ PTE without checking pte_present(), so swap/migration entries
+ decode random offset bits and a thread can stay parked on a stale
+ fault.
+
+ 6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to
+ mk_vma_flags() unconditionally, an out-of-bounds write into the
+ single-word vma_flags_t on 32-bit. Build the mask from config-gated
+ per-mode masks so an unavailable bit is never materialised.
+
+This patch (of 6):
+
+make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by
+calling huge_ptep_modify_prot_commit() with a ptent snapshot that was
+fetched without the corresponding huge_ptep_modify_prot_start(). The
+start helper is what atomically clears the entry so the kernel-owned
+snapshot stays consistent until the commit; without it, the hardware may
+set Dirty or Accessed in the live PTE between the original read and the
+commit, and huge_ptep_modify_prot_commit() (whose generic implementation
+just calls set_huge_pte_at()) then writes the stale snapshot back over the
+live hardware bits, losing the update.
+
+The non-hugetlb sibling make_uffd_wp_pte() does this correctly via
+ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern
+for the present-PTE branch. The migration case stays as-is -- migration
+entries are non-present, so there's no hardware update to race against.
+
+Link: https://lore.kernel.org/20260529172331.356655-1-kas@kernel.org
+Link: https://lore.kernel.org/20260529172331.356655-2-kas@kernel.org
+Link: https://lore.kernel.org/all/20260526130509.2748441-1-kirill@shutemov.name/ [1]
+Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Reviewed-by: Dev Jain <dev.jain@arm.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ kas: adapt to the pre-softleaf idiom; apply the
+ huge_ptep_modify_prot_start()/commit() fix to the present-PTE
+ (!huge_pte_none()) branch ]
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/task_mmu.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 673b7d0fcfd8fa..bc127f1ad4bb28 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -2254,15 +2254,19 @@ static void make_uffd_wp_huge_pte(struct vm_area_struct *vma,
+
+ psize = huge_page_size(hstate_vma(vma));
+
+- if (is_hugetlb_entry_migration(ptent))
++ if (is_hugetlb_entry_migration(ptent)) {
+ set_huge_pte_at(vma->vm_mm, addr, ptep,
+ pte_swp_mkuffd_wp(ptent), psize);
+- else if (!huge_pte_none(ptent))
+- huge_ptep_modify_prot_commit(vma, addr, ptep, ptent,
+- huge_pte_mkuffd_wp(ptent));
+- else
++ } else if (!huge_pte_none(ptent)) {
++ pte_t old_pte, new_pte;
++
++ old_pte = huge_ptep_modify_prot_start(vma, addr, ptep);
++ new_pte = huge_pte_mkuffd_wp(old_pte);
++ huge_ptep_modify_prot_commit(vma, addr, ptep, old_pte, new_pte);
++ } else {
+ set_huge_pte_at(vma->vm_mm, addr, ptep,
+ make_pte_marker(PTE_MARKER_UFFD_WP), psize);
++ }
+ }
+ #endif /* CONFIG_HUGETLB_PAGE */
+
+--
+2.53.0
+
--- /dev/null
+From c521ebd5e8627de5d903243604cca0f039c1f967 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:36 -0600
+Subject: netfilter: nf_tables: revert commit_mutex usage in reset path
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ]
+
+It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset
+and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set'
+rule run at the same time.
+
+Previous patches made it safe to run individual reset handlers concurrently
+so commit_mutex is no longer required to prevent this.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Link: https://lore.kernel.org/all/aUh_3mVRV8OrGsVo@strlen.de/
+Reported-by: <syzbot+ff16b505ec9152e5f448@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=ff16b505ec9152e5f448
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 248 ++++++----------------------------
+ 1 file changed, 42 insertions(+), 206 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 838c9f49e4e01a..09969379c43a73 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3719,23 +3719,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_rules(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- /* Mutex is held is to prevent that two concurrent dump-and-reset calls
+- * do not underrun counters and quotas. The commit_mutex is used for
+- * the lack a better lock, this is not transaction path.
+- */
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_rules(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ {
+ struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+@@ -3755,16 +3738,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ return -ENOMEM;
+ }
+ }
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb)
+-{
+- struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_rules_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_rules_done(struct netlink_callback *cb)
+@@ -3830,6 +3807,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
++ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -3843,47 +3822,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- skb2 = nf_tables_getrule_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, net, portid);
+-}
+-
+-static int nf_tables_getrule_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- u32 portid = NETLINK_CB(skb).portid;
+- struct net *net = info->net;
+- struct sk_buff *skb2;
+- char *buf;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start= nf_tables_dumpreset_rules_start,
+- .dump = nf_tables_dumpreset_rules,
+- .done = nf_tables_dump_rules_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getrule_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getrule_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_RULE_TABLE]),
+ (char *)nla_data(nla[NFTA_RULE_TABLE]),
+@@ -6107,6 +6055,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ nla_nest_end(skb, nest);
+ nlmsg_end(skb, nlh);
+
++ if (dump_ctx->reset && args.iter.count > args.iter.skip)
++ audit_log_nft_set_reset(table, cb->seq,
++ args.iter.count - args.iter.skip);
++
+ rcu_read_unlock();
+
+ if (args.iter.err && args.iter.err != -EMSGSIZE)
+@@ -6122,26 +6074,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ return -ENOSPC;
+ }
+
+-static int nf_tables_dumpreset_set(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- struct nft_set_dump_ctx *dump_ctx = cb->data;
+- int ret, skip = cb->args[0];
+-
+- mutex_lock(&nft_net->commit_mutex);
+-
+- ret = nf_tables_dump_set(skb, cb);
+-
+- if (cb->args[0] > skip)
+- audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq,
+- cb->args[0] - skip);
+-
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_set_start(struct netlink_callback *cb)
+ {
+ struct nft_set_dump_ctx *dump_ctx = cb->data;
+@@ -6385,8 +6317,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ {
+ struct netlink_ext_ack *extack = info->extack;
+ struct nft_set_dump_ctx dump_ctx;
++ int rem, err = 0, nelems = 0;
++ struct net *net = info->net;
+ struct nlattr *attr;
+- int rem, err = 0;
++ bool reset = false;
++
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
++ reset = true;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -6396,7 +6333,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ .module = THIS_MODULE,
+ };
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+@@ -6407,75 +6344,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+ return -EINVAL;
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+ nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false);
+- if (err < 0) {
+- NL_SET_BAD_ATTR(extack, attr);
+- break;
+- }
+- }
+-
+- return err;
+-}
+-
+-static int nf_tables_getsetelem_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- struct netlink_ext_ack *extack = info->extack;
+- struct nft_set_dump_ctx dump_ctx;
+- int rem, err = 0, nelems = 0;
+- struct nlattr *attr;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_set_start,
+- .dump = nf_tables_dumpreset_set,
+- .done = nf_tables_dump_set_done,
+- .module = THIS_MODULE,
+- };
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- return err;
+-
+- c.data = &dump_ctx;
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+- return -EINVAL;
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- rcu_read_lock();
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- goto out_unlock;
+-
+- nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true);
++ err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset);
+ if (err < 0) {
+ NL_SET_BAD_ATTR(extack, attr);
+ break;
+ }
+ nelems++;
+ }
+- audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems);
+-
+-out_unlock:
+- rcu_read_unlock();
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (reset)
++ audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net),
++ nelems);
+
+ return err;
+ }
+@@ -8182,19 +8065,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_obj(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_obj(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ {
+ struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+@@ -8211,16 +8081,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ if (nla[NFTA_OBJ_TYPE])
+ ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
+
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb)
+-{
+- struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_obj_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_obj_done(struct netlink_callback *cb)
+@@ -8282,42 +8146,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,
+ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- u32 portid = NETLINK_CB(skb).portid;
+- struct sk_buff *skb2;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_obj_start,
+- .dump = nf_tables_dump_obj,
+- .done = nf_tables_dump_obj_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- skb2 = nf_tables_getobj_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, info->net, portid);
+-}
+-
+-static int nf_tables_getobj_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
+ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+- .start = nf_tables_dumpreset_obj_start,
+- .dump = nf_tables_dumpreset_obj,
++ .start = nf_tables_dump_obj_start,
++ .dump = nf_tables_dump_obj,
+ .done = nf_tables_dump_obj_done,
+ .module = THIS_MODULE,
+ .data = (void *)nla,
+@@ -8326,18 +8164,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getobj_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getobj_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_OBJ_TABLE]),
+ (char *)nla_data(nla[NFTA_OBJ_TABLE]),
+@@ -9540,7 +9376,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_rule_policy,
+ },
+ [NFT_MSG_GETRULE_RESET] = {
+- .call = nf_tables_getrule_reset,
++ .call = nf_tables_getrule,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_RULE_MAX,
+ .policy = nft_rule_policy,
+@@ -9594,7 +9430,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_set_elem_list_policy,
+ },
+ [NFT_MSG_GETSETELEM_RESET] = {
+- .call = nf_tables_getsetelem_reset,
++ .call = nf_tables_getsetelem,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_SET_ELEM_LIST_MAX,
+ .policy = nft_set_elem_list_policy,
+@@ -9640,7 +9476,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_obj_policy,
+ },
+ [NFT_MSG_GETOBJ_RESET] = {
+- .call = nf_tables_getobj_reset,
++ .call = nf_tables_getobj,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_OBJ_MAX,
+ .policy = nft_obj_policy,
+--
+2.53.0
+
--- /dev/null
+From 47bbfcce532ae34c10759d24a321b19bb7571299 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:37 -0600
+Subject: netfilter: nft_counter: serialize reset with spinlock
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ]
+
+Add a global static spinlock to serialize counter fetch+reset
+operations, preventing concurrent dump-and-reset from underrunning
+values.
+
+The lock is taken before fetching the total so that two parallel
+resets cannot both read the same counter values and then both
+subtract them.
+
+A global lock is used for simplicity since resets are infrequent.
+If this becomes a bottleneck, it can be replaced with a per-net
+lock later.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_counter.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
+index 0d70325280cc57..169ae93688bcc5 100644
+--- a/net/netfilter/nft_counter.c
++++ b/net/netfilter/nft_counter.c
+@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv {
+
+ static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync);
+
++/* control plane only: sync fetch+reset */
++static DEFINE_SPINLOCK(nft_counter_lock);
++
+ static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv,
+ }
+ }
+
++static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv,
++ struct nft_counter_tot *total)
++{
++ spin_lock(&nft_counter_lock);
++ nft_counter_fetch(priv, total);
++ nft_counter_reset(priv, total);
++ spin_unlock(&nft_counter_lock);
++}
++
+ static int nft_counter_do_dump(struct sk_buff *skb,
+ struct nft_counter_percpu_priv *priv,
+ bool reset)
+ {
+ struct nft_counter_tot total;
+
+- nft_counter_fetch(priv, &total);
++ if (unlikely(reset))
++ nft_counter_fetch_and_reset(priv, &total);
++ else
++ nft_counter_fetch(priv, &total);
+
+ if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
+ NFTA_COUNTER_PAD) ||
+@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb,
+ NFTA_COUNTER_PAD))
+ goto nla_put_failure;
+
+- if (reset)
+- nft_counter_reset(priv, &total);
+-
+ return 0;
+
+ nla_put_failure:
+--
+2.53.0
+
--- /dev/null
+From 07749809d6857f884e1b16aa556cef9b83f13efe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:38 -0600
+Subject: netfilter: nft_quota: use atomic64_xchg for reset
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ]
+
+Use atomic64_xchg() to atomically read and zero the consumed value
+on reset, which is simpler than the previous read+sub pattern and
+doesn't require lock serialization.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_quota.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index df0798da2329b9..cb6c0e04ff6755 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ u64 consumed, consumed_cap, quota;
+ u32 flags = priv->flags;
+
+- /* Since we inconditionally increment consumed quota for each packet
++ /* Since we unconditionally increment consumed quota for each packet
+ * that we see, don't go over the quota boundary in what we send to
+ * userspace.
+ */
+- consumed = atomic64_read(priv->consumed);
++ if (reset) {
++ consumed = atomic64_xchg(priv->consumed, 0);
++ clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
++ } else {
++ consumed = atomic64_read(priv->consumed);
++ }
+ quota = atomic64_read(&priv->quota);
+ if (consumed >= quota) {
+ consumed_cap = quota;
+@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
+ goto nla_put_failure;
+
+- if (reset) {
+- atomic64_sub(consumed, priv->consumed);
+- clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+- }
+ return 0;
+
+ nla_put_failure:
+--
+2.53.0
+
--- /dev/null
+From 49c4710cc0804c5d854b37a3a6e18297ca4a17bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:08 +0800
+Subject: selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream.
+
+Extend the verifier_ld_ind BPF selftests with subprogs containing
+ld_{abs,ind} and craft the test in a way where the invalid register
+read is rejected in the fixed case. Also add a success case each,
+and add additional coverage related to the BTF return type enforcement.
+
+ # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind
+ [...]
+ #611/1 verifier_ld_ind/ld_ind: check calling conv, r1:OK
+ #611/2 verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK
+ #611/3 verifier_ld_ind/ld_ind: check calling conv, r2:OK
+ #611/4 verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK
+ #611/5 verifier_ld_ind/ld_ind: check calling conv, r3:OK
+ #611/6 verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK
+ #611/7 verifier_ld_ind/ld_ind: check calling conv, r4:OK
+ #611/8 verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK
+ #611/9 verifier_ld_ind/ld_ind: check calling conv, r5:OK
+ #611/10 verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK
+ #611/11 verifier_ld_ind/ld_ind: check calling conv, r7:OK
+ #611/12 verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK
+ #611/13 verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK
+ #611/14 verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK
+ #611/15 verifier_ld_ind/ld_abs: subprog with both paths safe:OK
+ #611/16 verifier_ld_ind/ld_ind: subprog with both paths safe:OK
+ #611/17 verifier_ld_ind/ld_abs: reject void return subprog:OK
+ #611/18 verifier_ld_ind/ld_ind: reject void return subprog:OK
+ #611 verifier_ld_ind:OK
+ Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED
+
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-4-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/progs/verifier_ld_ind.c | 142 ++++++++++++++++++
+ 1 file changed, 142 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+index c925ba9a2e74c2..09e81b99eecb4e 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
++++ b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+@@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void)
+ : __clobber_all);
+ }
+
++/*
++ * ld_{abs,ind} subprog that always sets r0=1 on the success path.
++ * bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper
++ * fails. The verifier must model this failure return so that callers
++ * account for r0=0 as a possible return value.
++ */
++__naked __noinline __used
++static int ldabs_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++__naked __noinline __used
++static int ldind_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog early exit on ld_abs failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_abs_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog early exit on ld_ind failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_ind_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog with both paths safe")
++__success
++__naked void ld_abs_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog with both paths safe")
++__success
++__naked void ld_ind_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++/*
++ * ld_{abs,ind} in subprogs require scalar (int) return type in BTF.
++ * A test with void return must be rejected.
++ */
++__naked __noinline __used
++static void ldabs_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_abs_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldabs_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++__naked __noinline __used
++static void ldind_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_ind_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldind_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
+ char _license[] SEC("license") = "GPL";
+--
+2.53.0
+
platform-x86-intel-uncore-freq-fix-current_freq_khz-.patch
net-airoha-move-airoha_eth-driver-in-a-dedicated-fol.patch
net-airoha-fix-skb-priority-underflow-in-airoha_dev_.patch
+bpf-fix-ld_-abs-ind-failure-path-analysis-in-subprog.patch
+selftests-bpf-add-tests-for-ld_-abs-ind-failure-path.patch
+netfilter-nft_counter-serialize-reset-with-spinlock.patch
+netfilter-nft_quota-use-atomic64_xchg-for-reset.patch
+netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch
+drm-virtio-fix-deadlock-in-display_info_cb-by-removi.patch
+fs-proc-task_mmu-fix-make_uffd_wp_huge_pte-prot-upda.patch
--- /dev/null
+From 8b3a33ebf9bf89cca304a2e10fef5916d1203c34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:07 +0800
+Subject: bpf: Fix ld_{abs,ind} failure path analysis in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit ee861486e377edc55361c08dcbceab3f6b6577bd upstream.
+
+Usage of ld_{abs,ind} instructions got extended into subprogs some time
+ago via commit 09b28d76eac4 ("bpf: Add abnormal return checks."). These
+are only allowed in subprograms when the latter are BTF annotated and
+have scalar return types.
+
+The code generator in bpf_gen_ld_abs() has an abnormal exit path (r0=0 +
+exit) from legacy cBPF times. While the enforcement is on scalar return
+types, the verifier must also simulate the path of abnormal exit if the
+packet data load via ld_{abs,ind} failed.
+
+This is currently not the case. Fix it by having the verifier simulate
+both success and failure paths, and extend it in similar ways as we do
+for tail calls. The success path (r0=unknown, continue to next insn) is
+pushed onto stack for later validation and the r0=0 and return to the
+caller is done on the fall-through side.
+
+Fixes: 09b28d76eac4 ("bpf: Add abnormal return checks.")
+Reported-by: STAR Labs SG <info@starlabs.sg>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-2-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+[ Dropped visit_abnormal_return_insn changes: depends on 7.0 symbols from
+ e40f5a6bf88a ("bpf: correct stack liveness for tail calls");
+ Hunk1: adapted IS_ERR/PTR_ERR to !branch/-EFAULT to match push_stack()
+ NULL-on-failure convention. ]
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index d1c51d812f3b66..463455180a8e35 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -17402,6 +17402,23 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ mark_reg_unknown(env, regs, BPF_REG_0);
+ /* ld_abs load up to 32-bit skb data. */
+ regs[BPF_REG_0].subreg_def = env->insn_idx + 1;
++ /*
++ * See bpf_gen_ld_abs() which emits a hidden BPF_EXIT with r0=0
++ * which must be explored by the verifier when in a subprog.
++ */
++ if (env->cur_state->curframe) {
++ struct bpf_verifier_state *branch;
++
++ mark_reg_scratched(env, BPF_REG_0);
++ branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
++ if (!branch)
++ return -EFAULT;
++ mark_reg_known_zero(env, regs, BPF_REG_0);
++ err = prepare_func_exit(env, &env->insn_idx);
++ if (err)
++ return err;
++ env->insn_idx--;
++ }
+ return 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 60c0c4cffc2072c69dfde68e5c6e40b82d9c9b0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 22:01:00 +0900
+Subject: drm/virtio: fix deadlock in display_info_cb by removing hotplug from
+ dequeue worker
+
+From: Ryosuke Yasuoka <ryasuoka@redhat.com>
+
+[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]
+
+A probe-time deadlock can occur between the dequeue worker and
+drm_client_register(). During probe, drm_client_register() holds
+clientlist_mutex and calls the fbdev hotplug callback, which triggers an
+atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
+waiting for virtqueue space. The dequeue worker that would free that
+space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
+drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
+to acquire the same clientlist_mutex. Since wake_up() is only called
+after the resp_cb loop, the probe thread is never woken and both threads
+deadlock.
+
+Fix this by removing the hotplug notification from
+virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info)
+is still updated synchronously in the callback.
+
+For the init path, drm_client_register() already fires an initial
+hotplug when the client is registered, which picks up the connector
+state updated by display_info_cb.
+
+For the runtime config_changed path, add a wait_event_timeout() in
+config_changed_work_func() so that display_info_cb updates the connector
+data before the hotplug notification is sent. Also replace
+drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since
+virtio-gpu never calls drm_kms_helper_poll_init() and thus
+drm_helper_hpd_irq_event() always returns false without doing anything.
+
+Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
+Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
+Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
+Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++-
+ drivers/gpu/drm/virtio/virtgpu_vq.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
+index 1c15cbf326b78c..4a25347734fda4 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
+@@ -48,7 +48,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
+ virtio_gpu_cmd_get_edids(vgdev);
+ virtio_gpu_cmd_get_display_info(vgdev);
+ virtio_gpu_notify(vgdev);
+- drm_helper_hpd_irq_event(vgdev->ddev);
++ wait_event_timeout(vgdev->resp_wq,
++ !vgdev->display_info_pending,
++ 5 * HZ);
++ drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+ events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index 8181b22b9b46a1..412384e16daea4 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -839,9 +839,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
+ vgdev->display_info_pending = false;
+ spin_unlock(&vgdev->display_info_lock);
+ wake_up(&vgdev->resp_wq);
+-
+- if (!drm_helper_hpd_irq_event(vgdev->ddev))
+- drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+
+ static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
+--
+2.53.0
+
--- /dev/null
+From 1fb7b87252e9b6ba3e250edddcba62956e2226fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 12:01:23 +0100
+Subject: fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+commit 04718f7c9290f95385f0dd328758753dc1c36dec upstream.
+
+Patch series "userfaultfd/pagemap: pre-existing fixes".
+
+These are pre-existing bug fixes that were carried at the front of the
+userfaultfd RWP working-set-tracking series up to v5 [1]. Per review
+feedback that fixes should not sit in the middle of a feature series, they
+are split out and sent on their own; the RWP series is reposted rebased on
+top of this.
+
+All six were flagged by the Sashiko AI review of the RWP series and carry
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>. They are
+independent of RWP, apply to mm-new directly, and carry Cc: stable@.
+
+ 1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in
+ make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates
+ when PAGEMAP_SCAN write-protects a hugetlb PTE.
+
+ 2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range
+ against HPAGE_SIZE rather than the hstate page size, so it never
+ write-protects gigantic hugetlb pages.
+
+ 3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an
+ unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole()
+ calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb
+ vma lock for read, and hugetlb_change_protection() then takes it
+ for write. Install the marker inline instead.
+
+ 4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp
+ on a device-private PMD permission downgrade, silently losing the
+ uffd-wp marker.
+
+ 5: userfaultfd: must_wait() applies pte_write() to a locklessly read
+ PTE without checking pte_present(), so swap/migration entries
+ decode random offset bits and a thread can stay parked on a stale
+ fault.
+
+ 6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to
+ mk_vma_flags() unconditionally, an out-of-bounds write into the
+ single-word vma_flags_t on 32-bit. Build the mask from config-gated
+ per-mode masks so an unavailable bit is never materialised.
+
+This patch (of 6):
+
+make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by
+calling huge_ptep_modify_prot_commit() with a ptent snapshot that was
+fetched without the corresponding huge_ptep_modify_prot_start(). The
+start helper is what atomically clears the entry so the kernel-owned
+snapshot stays consistent until the commit; without it, the hardware may
+set Dirty or Accessed in the live PTE between the original read and the
+commit, and huge_ptep_modify_prot_commit() (whose generic implementation
+just calls set_huge_pte_at()) then writes the stale snapshot back over the
+live hardware bits, losing the update.
+
+The non-hugetlb sibling make_uffd_wp_pte() does this correctly via
+ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern
+for the present-PTE branch. The migration case stays as-is -- migration
+entries are non-present, so there's no hardware update to race against.
+
+Link: https://lore.kernel.org/20260529172331.356655-1-kas@kernel.org
+Link: https://lore.kernel.org/20260529172331.356655-2-kas@kernel.org
+Link: https://lore.kernel.org/all/20260526130509.2748441-1-kirill@shutemov.name/ [1]
+Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Reviewed-by: Dev Jain <dev.jain@arm.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ kas: adapt to the pre-softleaf idiom; apply the
+ huge_ptep_modify_prot_start()/commit() fix to the present-PTE
+ (!huge_pte_none()) branch ]
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/proc/task_mmu.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 38b9d47426ca99..858b11009c269e 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -2485,15 +2485,19 @@ static void make_uffd_wp_huge_pte(struct vm_area_struct *vma,
+
+ psize = huge_page_size(hstate_vma(vma));
+
+- if (is_hugetlb_entry_migration(ptent))
++ if (is_hugetlb_entry_migration(ptent)) {
+ set_huge_pte_at(vma->vm_mm, addr, ptep,
+ pte_swp_mkuffd_wp(ptent), psize);
+- else if (!huge_pte_none(ptent))
+- huge_ptep_modify_prot_commit(vma, addr, ptep, ptent,
+- huge_pte_mkuffd_wp(ptent));
+- else
++ } else if (!huge_pte_none(ptent)) {
++ pte_t old_pte, new_pte;
++
++ old_pte = huge_ptep_modify_prot_start(vma, addr, ptep);
++ new_pte = huge_pte_mkuffd_wp(old_pte);
++ huge_ptep_modify_prot_commit(vma, addr, ptep, old_pte, new_pte);
++ } else {
+ set_huge_pte_at(vma->vm_mm, addr, ptep,
+ make_pte_marker(PTE_MARKER_UFFD_WP), psize);
++ }
+ }
+ #endif /* CONFIG_HUGETLB_PAGE */
+
+--
+2.53.0
+
--- /dev/null
+From 6b1304757f523ace8898896505d3108bbcc89a70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:36 -0600
+Subject: netfilter: nf_tables: revert commit_mutex usage in reset path
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ]
+
+It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset
+and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set'
+rule run at the same time.
+
+Previous patches made it safe to run individual reset handlers concurrently
+so commit_mutex is no longer required to prevent this.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Link: https://lore.kernel.org/all/aUh_3mVRV8OrGsVo@strlen.de/
+Reported-by: <syzbot+ff16b505ec9152e5f448@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=ff16b505ec9152e5f448
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 248 ++++++----------------------------
+ 1 file changed, 42 insertions(+), 206 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 0842916c19f503..c82c16bd4257e4 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3908,23 +3908,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_rules(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- /* Mutex is held is to prevent that two concurrent dump-and-reset calls
+- * do not underrun counters and quotas. The commit_mutex is used for
+- * the lack a better lock, this is not transaction path.
+- */
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_rules(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ {
+ struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+@@ -3944,16 +3927,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ return -ENOMEM;
+ }
+ }
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb)
+-{
+- struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_rules_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_rules_done(struct netlink_callback *cb)
+@@ -4019,6 +3996,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
++ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -4032,47 +4011,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- skb2 = nf_tables_getrule_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, net, portid);
+-}
+-
+-static int nf_tables_getrule_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- u32 portid = NETLINK_CB(skb).portid;
+- struct net *net = info->net;
+- struct sk_buff *skb2;
+- char *buf;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start= nf_tables_dumpreset_rules_start,
+- .dump = nf_tables_dumpreset_rules,
+- .done = nf_tables_dump_rules_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getrule_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getrule_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_RULE_TABLE]),
+ (char *)nla_data(nla[NFTA_RULE_TABLE]),
+@@ -6332,6 +6280,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ nla_nest_end(skb, nest);
+ nlmsg_end(skb, nlh);
+
++ if (dump_ctx->reset && args.iter.count > args.iter.skip)
++ audit_log_nft_set_reset(table, cb->seq,
++ args.iter.count - args.iter.skip);
++
+ rcu_read_unlock();
+
+ if (args.iter.err && args.iter.err != -EMSGSIZE)
+@@ -6347,26 +6299,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ return -ENOSPC;
+ }
+
+-static int nf_tables_dumpreset_set(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- struct nft_set_dump_ctx *dump_ctx = cb->data;
+- int ret, skip = cb->args[0];
+-
+- mutex_lock(&nft_net->commit_mutex);
+-
+- ret = nf_tables_dump_set(skb, cb);
+-
+- if (cb->args[0] > skip)
+- audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq,
+- cb->args[0] - skip);
+-
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_set_start(struct netlink_callback *cb)
+ {
+ struct nft_set_dump_ctx *dump_ctx = cb->data;
+@@ -6613,8 +6545,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ {
+ struct netlink_ext_ack *extack = info->extack;
+ struct nft_set_dump_ctx dump_ctx;
++ int rem, err = 0, nelems = 0;
++ struct net *net = info->net;
+ struct nlattr *attr;
+- int rem, err = 0;
++ bool reset = false;
++
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
++ reset = true;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -6624,7 +6561,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ .module = THIS_MODULE,
+ };
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+@@ -6635,75 +6572,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+ return -EINVAL;
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+ nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false);
+- if (err < 0) {
+- NL_SET_BAD_ATTR(extack, attr);
+- break;
+- }
+- }
+-
+- return err;
+-}
+-
+-static int nf_tables_getsetelem_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- struct netlink_ext_ack *extack = info->extack;
+- struct nft_set_dump_ctx dump_ctx;
+- int rem, err = 0, nelems = 0;
+- struct nlattr *attr;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_set_start,
+- .dump = nf_tables_dumpreset_set,
+- .done = nf_tables_dump_set_done,
+- .module = THIS_MODULE,
+- };
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- return err;
+-
+- c.data = &dump_ctx;
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+- return -EINVAL;
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- rcu_read_lock();
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- goto out_unlock;
+-
+- nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true);
++ err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset);
+ if (err < 0) {
+ NL_SET_BAD_ATTR(extack, attr);
+ break;
+ }
+ nelems++;
+ }
+- audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems);
+-
+-out_unlock:
+- rcu_read_unlock();
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (reset)
++ audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net),
++ nelems);
+
+ return err;
+ }
+@@ -8567,19 +8450,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_obj(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_obj(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ {
+ struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+@@ -8596,16 +8466,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ if (nla[NFTA_OBJ_TYPE])
+ ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
+
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb)
+-{
+- struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_obj_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_obj_done(struct netlink_callback *cb)
+@@ -8667,42 +8531,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,
+ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- u32 portid = NETLINK_CB(skb).portid;
+- struct sk_buff *skb2;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_obj_start,
+- .dump = nf_tables_dump_obj,
+- .done = nf_tables_dump_obj_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- skb2 = nf_tables_getobj_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, info->net, portid);
+-}
+-
+-static int nf_tables_getobj_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
+ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+- .start = nf_tables_dumpreset_obj_start,
+- .dump = nf_tables_dumpreset_obj,
++ .start = nf_tables_dump_obj_start,
++ .dump = nf_tables_dump_obj,
+ .done = nf_tables_dump_obj_done,
+ .module = THIS_MODULE,
+ .data = (void *)nla,
+@@ -8711,18 +8549,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getobj_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getobj_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_OBJ_TABLE]),
+ (char *)nla_data(nla[NFTA_OBJ_TABLE]),
+@@ -10030,7 +9866,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_rule_policy,
+ },
+ [NFT_MSG_GETRULE_RESET] = {
+- .call = nf_tables_getrule_reset,
++ .call = nf_tables_getrule,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_RULE_MAX,
+ .policy = nft_rule_policy,
+@@ -10084,7 +9920,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_set_elem_list_policy,
+ },
+ [NFT_MSG_GETSETELEM_RESET] = {
+- .call = nf_tables_getsetelem_reset,
++ .call = nf_tables_getsetelem,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_SET_ELEM_LIST_MAX,
+ .policy = nft_set_elem_list_policy,
+@@ -10130,7 +9966,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_obj_policy,
+ },
+ [NFT_MSG_GETOBJ_RESET] = {
+- .call = nf_tables_getobj_reset,
++ .call = nf_tables_getobj,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_OBJ_MAX,
+ .policy = nft_obj_policy,
+--
+2.53.0
+
--- /dev/null
+From 4a9110c30d5e1af7349390950df0bc7e9b4a14cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:37 -0600
+Subject: netfilter: nft_counter: serialize reset with spinlock
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ]
+
+Add a global static spinlock to serialize counter fetch+reset
+operations, preventing concurrent dump-and-reset from underrunning
+values.
+
+The lock is taken before fetching the total so that two parallel
+resets cannot both read the same counter values and then both
+subtract them.
+
+A global lock is used for simplicity since resets are infrequent.
+If this becomes a bottleneck, it can be replaced with a per-net
+lock later.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_counter.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
+index 0d70325280cc57..169ae93688bcc5 100644
+--- a/net/netfilter/nft_counter.c
++++ b/net/netfilter/nft_counter.c
+@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv {
+
+ static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync);
+
++/* control plane only: sync fetch+reset */
++static DEFINE_SPINLOCK(nft_counter_lock);
++
+ static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv,
+ }
+ }
+
++static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv,
++ struct nft_counter_tot *total)
++{
++ spin_lock(&nft_counter_lock);
++ nft_counter_fetch(priv, total);
++ nft_counter_reset(priv, total);
++ spin_unlock(&nft_counter_lock);
++}
++
+ static int nft_counter_do_dump(struct sk_buff *skb,
+ struct nft_counter_percpu_priv *priv,
+ bool reset)
+ {
+ struct nft_counter_tot total;
+
+- nft_counter_fetch(priv, &total);
++ if (unlikely(reset))
++ nft_counter_fetch_and_reset(priv, &total);
++ else
++ nft_counter_fetch(priv, &total);
+
+ if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
+ NFTA_COUNTER_PAD) ||
+@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb,
+ NFTA_COUNTER_PAD))
+ goto nla_put_failure;
+
+- if (reset)
+- nft_counter_reset(priv, &total);
+-
+ return 0;
+
+ nla_put_failure:
+--
+2.53.0
+
--- /dev/null
+From a3ef9fe7d75aac0a74fabd11231e810069a54360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:38 -0600
+Subject: netfilter: nft_quota: use atomic64_xchg for reset
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ]
+
+Use atomic64_xchg() to atomically read and zero the consumed value
+on reset, which is simpler than the previous read+sub pattern and
+doesn't require lock serialization.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_quota.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index df0798da2329b9..cb6c0e04ff6755 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ u64 consumed, consumed_cap, quota;
+ u32 flags = priv->flags;
+
+- /* Since we inconditionally increment consumed quota for each packet
++ /* Since we unconditionally increment consumed quota for each packet
+ * that we see, don't go over the quota boundary in what we send to
+ * userspace.
+ */
+- consumed = atomic64_read(priv->consumed);
++ if (reset) {
++ consumed = atomic64_xchg(priv->consumed, 0);
++ clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
++ } else {
++ consumed = atomic64_read(priv->consumed);
++ }
+ quota = atomic64_read(&priv->quota);
+ if (consumed >= quota) {
+ consumed_cap = quota;
+@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
+ goto nla_put_failure;
+
+- if (reset) {
+- atomic64_sub(consumed, priv->consumed);
+- clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+- }
+ return 0;
+
+ nla_put_failure:
+--
+2.53.0
+
--- /dev/null
+From d3b6095a981698eb7d0e7c72ff6ade902bcdedff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:08 +0800
+Subject: selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream.
+
+Extend the verifier_ld_ind BPF selftests with subprogs containing
+ld_{abs,ind} and craft the test in a way where the invalid register
+read is rejected in the fixed case. Also add a success case each,
+and add additional coverage related to the BTF return type enforcement.
+
+ # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind
+ [...]
+ #611/1 verifier_ld_ind/ld_ind: check calling conv, r1:OK
+ #611/2 verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK
+ #611/3 verifier_ld_ind/ld_ind: check calling conv, r2:OK
+ #611/4 verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK
+ #611/5 verifier_ld_ind/ld_ind: check calling conv, r3:OK
+ #611/6 verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK
+ #611/7 verifier_ld_ind/ld_ind: check calling conv, r4:OK
+ #611/8 verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK
+ #611/9 verifier_ld_ind/ld_ind: check calling conv, r5:OK
+ #611/10 verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK
+ #611/11 verifier_ld_ind/ld_ind: check calling conv, r7:OK
+ #611/12 verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK
+ #611/13 verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK
+ #611/14 verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK
+ #611/15 verifier_ld_ind/ld_abs: subprog with both paths safe:OK
+ #611/16 verifier_ld_ind/ld_ind: subprog with both paths safe:OK
+ #611/17 verifier_ld_ind/ld_abs: reject void return subprog:OK
+ #611/18 verifier_ld_ind/ld_ind: reject void return subprog:OK
+ #611 verifier_ld_ind:OK
+ Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED
+
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-4-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/progs/verifier_ld_ind.c | 142 ++++++++++++++++++
+ 1 file changed, 142 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+index c925ba9a2e74c2..09e81b99eecb4e 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
++++ b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+@@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void)
+ : __clobber_all);
+ }
+
++/*
++ * ld_{abs,ind} subprog that always sets r0=1 on the success path.
++ * bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper
++ * fails. The verifier must model this failure return so that callers
++ * account for r0=0 as a possible return value.
++ */
++__naked __noinline __used
++static int ldabs_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++__naked __noinline __used
++static int ldind_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog early exit on ld_abs failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_abs_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog early exit on ld_ind failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_ind_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog with both paths safe")
++__success
++__naked void ld_abs_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog with both paths safe")
++__success
++__naked void ld_ind_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++/*
++ * ld_{abs,ind} in subprogs require scalar (int) return type in BTF.
++ * A test with void return must be rejected.
++ */
++__naked __noinline __used
++static void ldabs_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_abs_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldabs_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++__naked __noinline __used
++static void ldind_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_ind_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldind_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
+ char _license[] SEC("license") = "GPL";
+--
+2.53.0
+
posix-timers-expand-timer_-re-arm-callbacks-with-a-b.patch
posix-cpu-timers-prevent-uaf-caused-by-non-leader-ex.patch
platform-x86-intel-uncore-freq-fix-current_freq_khz-.patch
+bpf-fix-ld_-abs-ind-failure-path-analysis-in-subprog.patch
+selftests-bpf-add-tests-for-ld_-abs-ind-failure-path.patch
+netfilter-nft_counter-serialize-reset-with-spinlock.patch
+netfilter-nft_quota-use-atomic64_xchg-for-reset.patch
+netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch
+drm-virtio-fix-deadlock-in-display_info_cb-by-removi.patch
+fs-proc-task_mmu-fix-make_uffd_wp_huge_pte-prot-upda.patch
--- /dev/null
+From 477e3f08c9d4e470f508dc8f21a8699830f01176 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:07 +0800
+Subject: bpf: Fix ld_{abs,ind} failure path analysis in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit ee861486e377edc55361c08dcbceab3f6b6577bd upstream.
+
+Usage of ld_{abs,ind} instructions got extended into subprogs some time
+ago via commit 09b28d76eac4 ("bpf: Add abnormal return checks."). These
+are only allowed in subprograms when the latter are BTF annotated and
+have scalar return types.
+
+The code generator in bpf_gen_ld_abs() has an abnormal exit path (r0=0 +
+exit) from legacy cBPF times. While the enforcement is on scalar return
+types, the verifier must also simulate the path of abnormal exit if the
+packet data load via ld_{abs,ind} failed.
+
+This is currently not the case. Fix it by having the verifier simulate
+both success and failure paths, and extend it in similar ways as we do
+for tail calls. The success path (r0=unknown, continue to next insn) is
+pushed onto stack for later validation and the r0=0 and return to the
+caller is done on the fall-through side.
+
+Fixes: 09b28d76eac4 ("bpf: Add abnormal return checks.")
+Reported-by: STAR Labs SG <info@starlabs.sg>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-2-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+[ Dropped visit_abnormal_return_insn changes: depends on 7.0 symbols from
+ e40f5a6bf88a ("bpf: correct stack liveness for tail calls");
+ Hunk1: adapted IS_ERR/PTR_ERR to !branch/-EFAULT to match push_stack()
+ NULL-on-failure convention. ]
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 1da0092122c1db..5e094c12fc94c5 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -15120,6 +15120,23 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ mark_reg_unknown(env, regs, BPF_REG_0);
+ /* ld_abs load up to 32-bit skb data. */
+ regs[BPF_REG_0].subreg_def = env->insn_idx + 1;
++ /*
++ * See bpf_gen_ld_abs() which emits a hidden BPF_EXIT with r0=0
++ * which must be explored by the verifier when in a subprog.
++ */
++ if (env->cur_state->curframe) {
++ struct bpf_verifier_state *branch;
++
++ mark_reg_scratched(env, BPF_REG_0);
++ branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
++ if (!branch)
++ return -EFAULT;
++ mark_reg_known_zero(env, regs, BPF_REG_0);
++ err = prepare_func_exit(env, &env->insn_idx);
++ if (err)
++ return err;
++ env->insn_idx--;
++ }
+ return 0;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 09ef4b7a3b15ae1f5471cf07728820c038354e3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 22:01:00 +0900
+Subject: drm/virtio: fix deadlock in display_info_cb by removing hotplug from
+ dequeue worker
+
+From: Ryosuke Yasuoka <ryasuoka@redhat.com>
+
+[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]
+
+A probe-time deadlock can occur between the dequeue worker and
+drm_client_register(). During probe, drm_client_register() holds
+clientlist_mutex and calls the fbdev hotplug callback, which triggers an
+atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
+waiting for virtqueue space. The dequeue worker that would free that
+space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
+drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
+to acquire the same clientlist_mutex. Since wake_up() is only called
+after the resp_cb loop, the probe thread is never woken and both threads
+deadlock.
+
+Fix this by removing the hotplug notification from
+virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info)
+is still updated synchronously in the callback.
+
+For the init path, drm_client_register() already fires an initial
+hotplug when the client is registered, which picks up the connector
+state updated by display_info_cb.
+
+For the runtime config_changed path, add a wait_event_timeout() in
+config_changed_work_func() so that display_info_cb updates the connector
+data before the hotplug notification is sent. Also replace
+drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since
+virtio-gpu never calls drm_kms_helper_poll_init() and thus
+drm_helper_hpd_irq_event() always returns false without doing anything.
+
+Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
+Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
+Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
+Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++-
+ drivers/gpu/drm/virtio/virtgpu_vq.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
+index 5a3b5aaed1f361..c88456bc9fcc00 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
+@@ -48,7 +48,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
+ virtio_gpu_cmd_get_edids(vgdev);
+ virtio_gpu_cmd_get_display_info(vgdev);
+ virtio_gpu_notify(vgdev);
+- drm_helper_hpd_irq_event(vgdev->ddev);
++ wait_event_timeout(vgdev->resp_wq,
++ !vgdev->display_info_pending,
++ 5 * HZ);
++ drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+ events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index b1a00c0c25a70b..fbafa44a726453 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -669,9 +669,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
+ vgdev->display_info_pending = false;
+ spin_unlock(&vgdev->display_info_lock);
+ wake_up(&vgdev->resp_wq);
+-
+- if (!drm_helper_hpd_irq_event(vgdev->ddev))
+- drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+
+ static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
+--
+2.53.0
+
--- /dev/null
+From 295d1cf7e341d3d27dccefd8775ad6d71ad0ac93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 18:54:02 +0200
+Subject: platform/x86/amd/pmc: Avoid logging "(null)" for DMI values
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Gibson <daniel@gibson.sh>
+
+commit a0738abd042f7406edd2175a819cf2e66388ed97 upstream.
+
+dmi_get_system_info(...) can return NULL. Using that as %s arguments
+of dev_info() would log "(null)" (as part of a message like
+'... System Vendor: "(null)", Product Name: "(null)" ...'), which may
+be confusing for users.
+
+Use Elvis operator to print "(Unknown)" instead.
+
+Fixes: 428b9fd2dce5 ("platform/x86/amd/pmc: Add delay_suspend module parameter")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202606251540.Nr2BtaNu-lkp@intel.com/
+Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Daniel Gibson <daniel@gibson.sh>
+Link: https://patch.msgid.link/20260626220210.1761783-2-daniel@gibson.sh
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/amd/pmc/pmc.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
+index b0951236887797..bf6c7ca247e243 100644
+--- a/drivers/platform/x86/amd/pmc/pmc.c
++++ b/drivers/platform/x86/amd/pmc/pmc.c
+@@ -852,11 +852,11 @@ static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev)
+ } else if (delay_suspend == 1) {
+ if (!intermediate_wakeup)
+ dev_info(pdev->dev, "Delaying suspend by 2.5s because delay_suspend=1. If this solves problems on your machine, please report this whole line to: platform-driver-x86@vger.kernel.org so it can be automatically detected as affected in the future. System Vendor: \"%s\" Product Name: \"%s\" Product Family: \"%s\" Board Vendor: \"%s\" Board Name: \"%s\"\n",
+- dmi_get_system_info(DMI_SYS_VENDOR),
+- dmi_get_system_info(DMI_PRODUCT_NAME),
+- dmi_get_system_info(DMI_PRODUCT_FAMILY),
+- dmi_get_system_info(DMI_BOARD_VENDOR),
+- dmi_get_system_info(DMI_BOARD_NAME));
++ dmi_get_system_info(DMI_SYS_VENDOR) ?: "(Unknown)",
++ dmi_get_system_info(DMI_PRODUCT_NAME) ?: "(Unknown)",
++ dmi_get_system_info(DMI_PRODUCT_FAMILY) ?: "(Unknown)",
++ dmi_get_system_info(DMI_BOARD_VENDOR) ?: "(Unknown)",
++ dmi_get_system_info(DMI_BOARD_NAME) ?: "(Unknown)");
+ return true;
+ }
+ return false;
+--
+2.53.0
+
--- /dev/null
+From c5e4d6584db2775f800e78be3e2b442957eb7c40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 18:54:01 +0200
+Subject: platform/x86/amd/pmc: Don't log during intermediate wakeups
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Daniel Gibson <daniel@gibson.sh>
+
+commit 037f0b03c663a247366673a807834389107995b7 upstream.
+
+The ECs in the IdeaPads that need the delay_suspend quirk send lots
+of messages when charging, which not only causes intermediate wakeups
+when suspended, but also prevents the device from reaching the deepest
+suspend state.
+
+Because of this amd_pmc_intermediate_wakeup_need_delay() returns false
+during intermediate wakeups and amd_pmc_want_suspend_delay() is called.
+So far it always logged its "Delaying suspend by 2.5s ..." messages
+then, which spams dmesg. This commit makes sure that those messages are
+only logged once per suspend.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221383
+Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
+Signed-off-by: Daniel Gibson <daniel@gibson.sh>
+Link: https://patch.msgid.link/20260611150426.3683372-5-daniel@gibson.sh
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/platform/x86/amd/pmc/pmc.c | 39 ++++++++++++++++++++++++------
+ drivers/platform/x86/amd/pmc/pmc.h | 1 +
+ 2 files changed, 32 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
+index d5b543f74a22db..b0951236887797 100644
+--- a/drivers/platform/x86/amd/pmc/pmc.c
++++ b/drivers/platform/x86/amd/pmc/pmc.c
+@@ -811,6 +811,20 @@ static bool amd_pmc_intermediate_wakeup_need_delay(struct amd_pmc_dev *pdev)
+
+ static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev)
+ {
++ /*
++ * intermediate_wakeup implies that the machine didn't get to deepest sleep
++ * state before - otherwise this function isn't called in amd_pmc_s2idle_check()
++ * because amd_pmc_intermediate_wakeup_need_delay() returns true first.
++ * On some IdeaPads that happens when charging, because the EC seems
++ * to send lots of messages then that wake the machine.
++ *
++ * But even in that case, the sleep here is necessary (on those IdeaPads),
++ * otherwise they wake up completely (resume) after a few seconds.
++ * So this variable is only used to avoid spamming dmesg on each
++ * intermediate wakeup.
++ */
++ bool intermediate_wakeup = !pdev->is_first_check_after_suspend;
++
+ /*
+ * Some Lenovo Laptops (like different IdeaPad 3 Slims) need some
+ * me-time before sleeping or they get uncooperative after waking
+@@ -829,17 +843,20 @@ static bool amd_pmc_want_suspend_delay(struct amd_pmc_dev *pdev)
+ * disabled with disable_workarounds or delay_suspend=0
+ */
+ if (delay_suspend == 1 || (delay_suspend == -1 && !disable_workarounds)) {
+- dev_info(pdev->dev, "Delaying suspend by 2.5s to avoid platform bug\n");
++ if (!intermediate_wakeup)
++ dev_info(pdev->dev, "Delaying suspend by 2.5s to avoid platform bug\n");
+ return true;
+ }
+- dev_info(pdev->dev, "Not delaying suspend because of module parameter, even though your device is assumed to need it!\n");
++ if (!intermediate_wakeup)
++ dev_info(pdev->dev, "Not delaying suspend because of module parameter, even though your device is assumed to need it!\n");
+ } else if (delay_suspend == 1) {
+- dev_info(pdev->dev, "Delaying suspend by 2.5s because delay_suspend=1. If this solves problems on your machine, please report this whole line to: platform-driver-x86@vger.kernel.org so it can be automatically detected as affected in the future. System Vendor: \"%s\" Product Name: \"%s\" Product Family: \"%s\" Board Vendor: \"%s\" Board Name: \"%s\"\n",
+- dmi_get_system_info(DMI_SYS_VENDOR),
+- dmi_get_system_info(DMI_PRODUCT_NAME),
+- dmi_get_system_info(DMI_PRODUCT_FAMILY),
+- dmi_get_system_info(DMI_BOARD_VENDOR),
+- dmi_get_system_info(DMI_BOARD_NAME));
++ if (!intermediate_wakeup)
++ dev_info(pdev->dev, "Delaying suspend by 2.5s because delay_suspend=1. If this solves problems on your machine, please report this whole line to: platform-driver-x86@vger.kernel.org so it can be automatically detected as affected in the future. System Vendor: \"%s\" Product Name: \"%s\" Product Family: \"%s\" Board Vendor: \"%s\" Board Name: \"%s\"\n",
++ dmi_get_system_info(DMI_SYS_VENDOR),
++ dmi_get_system_info(DMI_PRODUCT_NAME),
++ dmi_get_system_info(DMI_PRODUCT_FAMILY),
++ dmi_get_system_info(DMI_BOARD_VENDOR),
++ dmi_get_system_info(DMI_BOARD_NAME));
+ return true;
+ }
+ return false;
+@@ -852,6 +869,9 @@ static void amd_pmc_s2idle_prepare(void)
+ u8 msg;
+ u32 arg = 1;
+
++ /* Reset this variable because this is a fresh suspend */
++ pdev->is_first_check_after_suspend = true;
++
+ /* Reset and Start SMU logging - to monitor the s0i3 stats */
+ amd_pmc_setup_smu_logging(pdev);
+
+@@ -891,6 +911,9 @@ static void amd_pmc_s2idle_check(void)
+ rc = amd_pmc_write_stb(pdev, AMD_PMC_STB_S2IDLE_CHECK);
+ if (rc)
+ dev_err(pdev->dev, "error writing to STB: %d\n", rc);
++
++ /* remember that first check after suspend is done (until next prepare) */
++ pdev->is_first_check_after_suspend = false;
+ }
+
+ static int amd_pmc_dump_data(struct amd_pmc_dev *pdev)
+diff --git a/drivers/platform/x86/amd/pmc/pmc.h b/drivers/platform/x86/amd/pmc/pmc.h
+index 5e7b8d5dc5d624..bea65810de5ab6 100644
+--- a/drivers/platform/x86/amd/pmc/pmc.h
++++ b/drivers/platform/x86/amd/pmc/pmc.h
+@@ -37,6 +37,7 @@ struct amd_pmc_dev {
+ struct dentry *dbgfs_dir;
+ struct quirk_entry *quirks;
+ bool disable_8042_wakeup;
++ bool is_first_check_after_suspend;
+ };
+
+ void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev);
+--
+2.53.0
+
--- /dev/null
+From 0ccd05109e62f37f8364fcfe1f962026cda29a77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2026 15:39:08 +0800
+Subject: selftests/bpf: Add tests for ld_{abs,ind} failure path in subprogs
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit e0fcb42bc6f41bab2895757d6610616b3820eff7 upstream.
+
+Extend the verifier_ld_ind BPF selftests with subprogs containing
+ld_{abs,ind} and craft the test in a way where the invalid register
+read is rejected in the fixed case. Also add a success case each,
+and add additional coverage related to the BTF return type enforcement.
+
+ # LDLIBS=-static PKG_CONFIG='pkg-config --static' ./vmtest.sh -- ./test_progs -t verifier_ld_ind
+ [...]
+ #611/1 verifier_ld_ind/ld_ind: check calling conv, r1:OK
+ #611/2 verifier_ld_ind/ld_ind: check calling conv, r1 @unpriv:OK
+ #611/3 verifier_ld_ind/ld_ind: check calling conv, r2:OK
+ #611/4 verifier_ld_ind/ld_ind: check calling conv, r2 @unpriv:OK
+ #611/5 verifier_ld_ind/ld_ind: check calling conv, r3:OK
+ #611/6 verifier_ld_ind/ld_ind: check calling conv, r3 @unpriv:OK
+ #611/7 verifier_ld_ind/ld_ind: check calling conv, r4:OK
+ #611/8 verifier_ld_ind/ld_ind: check calling conv, r4 @unpriv:OK
+ #611/9 verifier_ld_ind/ld_ind: check calling conv, r5:OK
+ #611/10 verifier_ld_ind/ld_ind: check calling conv, r5 @unpriv:OK
+ #611/11 verifier_ld_ind/ld_ind: check calling conv, r7:OK
+ #611/12 verifier_ld_ind/ld_ind: check calling conv, r7 @unpriv:OK
+ #611/13 verifier_ld_ind/ld_abs: subprog early exit on ld_abs failure:OK
+ #611/14 verifier_ld_ind/ld_ind: subprog early exit on ld_ind failure:OK
+ #611/15 verifier_ld_ind/ld_abs: subprog with both paths safe:OK
+ #611/16 verifier_ld_ind/ld_ind: subprog with both paths safe:OK
+ #611/17 verifier_ld_ind/ld_abs: reject void return subprog:OK
+ #611/18 verifier_ld_ind/ld_ind: reject void return subprog:OK
+ #611 verifier_ld_ind:OK
+ Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED
+
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Link: https://lore.kernel.org/r/20260408191242.526279-4-daniel@iogearbox.net
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/progs/verifier_ld_ind.c | 142 ++++++++++++++++++
+ 1 file changed, 142 insertions(+)
+
+diff --git a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+index c925ba9a2e74c2..09e81b99eecb4e 100644
+--- a/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
++++ b/tools/testing/selftests/bpf/progs/verifier_ld_ind.c
+@@ -107,4 +107,146 @@ __naked void ind_check_calling_conv_r7(void)
+ : __clobber_all);
+ }
+
++/*
++ * ld_{abs,ind} subprog that always sets r0=1 on the success path.
++ * bpf_gen_ld_abs() emits a hidden exit with r0=0 when the load helper
++ * fails. The verifier must model this failure return so that callers
++ * account for r0=0 as a possible return value.
++ */
++__naked __noinline __used
++static int ldabs_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++__naked __noinline __used
++static int ldind_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog early exit on ld_abs failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_abs_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog early exit on ld_ind failure")
++__failure __msg("R9 !read_ok")
++__naked void ld_ind_subprog_early_exit(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "if r0 != 0 goto l_exit_%=;"
++ "r0 = r9;"
++ "l_exit_%=:"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: subprog with both paths safe")
++__success
++__naked void ld_abs_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldabs_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: subprog with both paths safe")
++__success
++__naked void ld_ind_subprog_both_paths_safe(void)
++{
++ asm volatile (
++ "call ldind_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++/*
++ * ld_{abs,ind} in subprogs require scalar (int) return type in BTF.
++ * A test with void return must be rejected.
++ */
++__naked __noinline __used
++static void ldabs_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ ".8byte %[ld_abs];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_abs, BPF_LD_ABS(BPF_W, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_abs: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_abs_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldabs_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
++__naked __noinline __used
++static void ldind_void_subprog(void)
++{
++ asm volatile (
++ "r6 = r1;"
++ "r7 = 0;"
++ ".8byte %[ld_ind];"
++ "r0 = 1;"
++ "exit;"
++ :
++ : __imm_insn(ld_ind, BPF_LD_IND(BPF_W, BPF_REG_7, 0))
++ : __clobber_all);
++}
++
++SEC("socket")
++__description("ld_ind: reject void return subprog")
++__failure __msg("LD_ABS is only allowed in functions that return 'int'")
++__naked void ld_ind_void_subprog_reject(void)
++{
++ asm volatile (
++ "call ldind_void_subprog;"
++ "r0 = 0;"
++ "exit;"
++ ::: __clobber_all);
++}
++
+ char _license[] SEC("license") = "GPL";
+--
+2.53.0
+
platform-x86-intel-uncore-freq-fix-current_freq_khz-.patch
+bpf-fix-ld_-abs-ind-failure-path-analysis-in-subprog.patch
+selftests-bpf-add-tests-for-ld_-abs-ind-failure-path.patch
+drm-virtio-fix-deadlock-in-display_info_cb-by-removi.patch
+platform-x86-amd-pmc-don-t-log-during-intermediate-w.patch
+platform-x86-amd-pmc-avoid-logging-null-for-dmi-valu.patch
--- /dev/null
+From 29b70c650570e1fad7a5efe475d0376eadc4f1e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Jul 2026 22:01:00 +0900
+Subject: drm/virtio: fix deadlock in display_info_cb by removing hotplug from
+ dequeue worker
+
+From: Ryosuke Yasuoka <ryasuoka@redhat.com>
+
+[ Upstream commit d1b894c5bbb3fee0012bd14356286dc2384e8213 ]
+
+A probe-time deadlock can occur between the dequeue worker and
+drm_client_register(). During probe, drm_client_register() holds
+clientlist_mutex and calls the fbdev hotplug callback, which triggers an
+atomic commit that ends up sleeping in virtio_gpu_queue_ctrl_sgs()
+waiting for virtqueue space. The dequeue worker that would free that
+space calls virtio_gpu_cmd_get_display_info_cb(), which invokes
+drm_kms_helper_hotplug_event() -> drm_client_dev_hotplug(), attempting
+to acquire the same clientlist_mutex. Since wake_up() is only called
+after the resp_cb loop, the probe thread is never woken and both threads
+deadlock.
+
+Fix this by removing the hotplug notification from
+virtio_gpu_cmd_get_display_info_cb(). The display data (outputs[i].info)
+is still updated synchronously in the callback.
+
+For the init path, drm_client_register() already fires an initial
+hotplug when the client is registered, which picks up the connector
+state updated by display_info_cb.
+
+For the runtime config_changed path, add a wait_event_timeout() in
+config_changed_work_func() so that display_info_cb updates the connector
+data before the hotplug notification is sent. Also replace
+drm_helper_hpd_irq_event() with drm_kms_helper_hotplug_event() since
+virtio-gpu never calls drm_kms_helper_poll_init() and thus
+drm_helper_hpd_irq_event() always returns false without doing anything.
+
+Fixes: 27655b9bb9f0 ("drm/client: Send hotplug event after registering a client")
+Closes: https://syzkaller.appspot.com/bug?id=d6dd6f86d3aaf7eebe7406e45c1c6e549453f224
+Closes: https://syzkaller.appspot.com/bug?id=908bd910da5dd79b88de4cf7baf376cc873a922e
+Suggested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Link: https://patch.msgid.link/20260713-virtiogpu_syzbot-v2-1-2958fa37d46d@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_kms.c | 5 ++++-
+ drivers/gpu/drm/virtio/virtgpu_vq.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
+index 80ba69b4860bc5..b79fd8350b6a47 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
++++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
+@@ -49,7 +49,10 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
+ virtio_gpu_cmd_get_edids(vgdev);
+ virtio_gpu_cmd_get_display_info(vgdev);
+ virtio_gpu_notify(vgdev);
+- drm_helper_hpd_irq_event(vgdev->ddev);
++ wait_event_timeout(vgdev->resp_wq,
++ !vgdev->display_info_pending,
++ 5 * HZ);
++ drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+ events_clear |= VIRTIO_GPU_EVENT_DISPLAY;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index 67865810a2e708..337189b15ad01b 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -840,9 +840,6 @@ static void virtio_gpu_cmd_get_display_info_cb(struct virtio_gpu_device *vgdev,
+ vgdev->display_info_pending = false;
+ spin_unlock(&vgdev->display_info_lock);
+ wake_up(&vgdev->resp_wq);
+-
+- if (!drm_helper_hpd_irq_event(vgdev->ddev))
+- drm_kms_helper_hotplug_event(vgdev->ddev);
+ }
+
+ static void virtio_gpu_cmd_get_capset_info_cb(struct virtio_gpu_device *vgdev,
+--
+2.53.0
+
platform-x86-intel-uncore-freq-fix-current_freq_khz-.patch
sched_ext-skip-ops.set_weight-for-disabled-tasks.patch
+drm-virtio-fix-deadlock-in-display_info_cb-by-removi.patch