From: Sasha Levin Date: Tue, 19 May 2026 01:21:31 +0000 (-0400) Subject: Fixes for all trees X-Git-Tag: v6.6.141~68 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=36bfd74ea9b9c512aed1f107ccdd5edbdb1065e1;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/alarmtimer-check-rtc-features-instead-of-ops.patch b/queue-5.10/alarmtimer-check-rtc-features-instead-of-ops.patch new file mode 100644 index 0000000000..ff3a825b54 --- /dev/null +++ b/queue-5.10/alarmtimer-check-rtc-features-instead-of-ops.patch @@ -0,0 +1,45 @@ +From 0d310a25a3c0bb572521dab1f55763a481365ad1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 May 2021 03:45:16 +0200 +Subject: alarmtimer: Check RTC features instead of ops + +From: Alexandre Belloni + +[ Upstream commit e09784a8a751e539dffc94d43bc917b0ac1e934a ] + +RTC drivers used to leave .set_alarm() NULL in order to signal the RTC +device doesn't support alarms. The drivers are now clearing the +RTC_FEATURE_ALARM bit for that purpose in order to keep the rtc_class_ops +structure const. So now, .set_alarm() is set unconditionally and this +possibly causes the alarmtimer code to select an RTC device that doesn't +support alarms. + +Test RTC_FEATURE_ALARM instead of relying on ops->set_alarm to determine +whether alarms are available. + +Fixes: 7ae41220ef58 ("rtc: introduce features bitfield") +Signed-off-by: Alexandre Belloni +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210511014516.563031-1-alexandre.belloni@bootlin.com +Signed-off-by: Sasha Levin +--- + kernel/time/alarmtimer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c +index 771b31018517a..976974edb355d 100644 +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -92,7 +92,7 @@ static int alarmtimer_rtc_add_device(struct device *dev, + if (rtcdev) + return -EBUSY; + +- if (!rtc->ops->set_alarm) ++ if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) + return -1; + if (!device_may_wakeup(rtc->dev.parent)) + return -1; +-- +2.53.0 + diff --git a/queue-5.10/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch b/queue-5.10/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch new file mode 100644 index 0000000000..e81639b33c --- /dev/null +++ b/queue-5.10/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch @@ -0,0 +1,75 @@ +From 4e34f8d13a4a958b4895abd939d75c9dff4f39a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Apr 2026 16:58:56 +0100 +Subject: btrfs: tracepoints: fix sleep while in atomic context in + btrfs_sync_file() + +From: Filipe Manana + +[ Upstream commit c73370c677646e86fc4b1780fb07027bdf847375 ] + +The trace event btrfs_sync_file() is called in an atomic context (all trace +events are) and its call to dput(), which is needed due to the call to +dget_parent(), can sleep, triggering a kernel splat. + +This can be reproduced by enabling the trace event and running btrfs/056 +from fstests for example. The splat shown in dmesg is the following: + + [53.919] BUG: sleeping function called from invalid context at fs/dcache.c:970 + [53.947] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 32773, name: xfs_io + [53.988] preempt_count: 2, expected: 0 + [53.967] RCU nest depth: 0, expected: 0 + [53.943] Preemption disabled at: + [53.944] [<0000000000000000>] 0x0 + [54.078] CPU: 0 UID: 0 PID: 32773 Comm: xfs_io Tainted: G W 7.1.0-rc1-btrfs-next-232+ #1 PREEMPT(full) + [54.070] Tainted: [W]=WARN + [54.071] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 + [54.072] Call Trace: + [54.074] + [54.076] dump_stack_lvl+0x56/0x80 + [54.079] __might_resched.cold+0xd6/0x10f + [54.072] dput.part.0+0x24/0x110 + [54.078] trace_event_raw_event_btrfs_sync_file+0x75/0x140 [btrfs] + [54.089] btrfs_sync_file+0x1ed/0x530 [btrfs] + [54.087] ? __handle_mm_fault+0x8ae/0xed0 + [54.089] btrfs_do_write_iter+0x172/0x210 [btrfs] + [54.091] vfs_write+0x21f/0x450 + [54.094] __x64_sys_pwrite64+0x8d/0xc0 + [54.096] ? do_user_addr_fault+0x20c/0x670 + [54.099] do_syscall_64+0x60/0xf20 + [54.092] ? clear_bhb_loop+0x60/0xb0 + [54.094] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +So stop using dget_parent() and dput() and access the parent dentry +directly as dentry->d_parent. This is also what ext4 is doing in +its equivalent trace event ext4_sync_file_enter(). + +Fixes: a85b46db143f ("btrfs: tracepoints: get correct superblock from dentry in event btrfs_sync_file()") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + include/trace/events/btrfs.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h +index 7e6fcbc6c6c55..dc816accaf38a 100644 +--- a/include/trace/events/btrfs.h ++++ b/include/trace/events/btrfs.h +@@ -699,10 +699,8 @@ TRACE_EVENT(btrfs_sync_file, + TP_fast_assign( + struct dentry *dentry = file_dentry(file); + struct inode *inode = file_inode(file); +- struct dentry *parent = dget_parent(dentry); +- struct inode *parent_inode = d_inode(parent); ++ struct inode *parent_inode = d_inode(dentry->d_parent); + +- dput(parent); + TP_fast_assign_fsid(btrfs_sb(inode->i_sb)); + __entry->ino = btrfs_ino(BTRFS_I(inode)); + __entry->parent = btrfs_ino(BTRFS_I(parent_inode)); +-- +2.53.0 + diff --git a/queue-5.10/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch b/queue-5.10/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch new file mode 100644 index 0000000000..d6cd317c21 --- /dev/null +++ b/queue-5.10/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch @@ -0,0 +1,60 @@ +From d7218543ccf83b00e5c9258b468761d865990367 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 15:48:08 +0800 +Subject: flow_dissector: Do not count vlan tags inside tunnel payload + +From: Qingqing Yang + +[ Upstream commit 9f87eb4246994e32a4e4ea88476b20ab3b412840 ] + +We've met the problem that when there is a vlan tag inside +GRE encapsulation, the match of num_of_vlans fails. +It is caused by the vlan tag inside GRE payload has been +counted into num_of_vlans, which is not expected. + +One example packet is like this: +Ethernet II, Src: Broadcom_68:56:07 (00:10:18:68:56:07) + Dst: Broadcom_68:56:08 (00:10:18:68:56:08) +802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 100 +Internet Protocol Version 4, Src: 192.168.1.4, Dst: 192.168.1.200 +Generic Routing Encapsulation (Transparent Ethernet bridging) +Ethernet II, Src: Broadcom_68:58:07 (00:10:18:68:58:07) + Dst: Broadcom_68:58:08 (00:10:18:68:58:08) +802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 200 +... +It should match the (num_of_vlans 1) rule, but it matches +the (num_of_vlans 2) rule. + +The vlan tags inside the GRE or other tunnel encapsulated payload +should not be taken into num_of_vlans. +The fix is to stop counting the vlan number when the encapsulation +bit is set. + +Fixes: 34951fcf26c5 ("flow_dissector: Add number of vlan tags dissector") +Signed-off-by: Qingqing Yang +Reviewed-by: Boris Sukholitko +Link: https://lore.kernel.org/r/20220919074808.136640-1-qingqing.yang@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 86eb489ee76e0..10e9d6e47e0a3 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1170,8 +1170,8 @@ bool __skb_flow_dissect(const struct net *net, + nhoff += sizeof(*vlan); + } + +- if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_NUM_OF_VLANS)) { ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_NUM_OF_VLANS) && ++ !(key_control->flags & FLOW_DIS_ENCAPSULATION)) { + struct flow_dissector_key_num_of_vlans *key_nvs; + + key_nvs = skb_flow_dissector_target(flow_dissector, +-- +2.53.0 + diff --git a/queue-5.10/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch b/queue-5.10/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch new file mode 100644 index 0000000000..06ce7667d6 --- /dev/null +++ b/queue-5.10/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch @@ -0,0 +1,97 @@ +From 708ccfde6ec1ecf18ad0b6d9e6bf1b7e87dee9ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Apr 2026 10:24:50 +0800 +Subject: flow_dissector: do not dissect PPPoE PFC frames + +From: Qingfang Deng + +[ Upstream commit d6c19b31a3c1d519fabdcf0aa239e6b6109b9473 ] + +RFC 2516 Section 7 states that Protocol Field Compression (PFC) is NOT +RECOMMENDED for PPPoE. In practice, pppd does not support negotiating +PFC for PPPoE sessions, and the flow dissector driver has assumed an +uncompressed frame until the blamed commit. + +During the review process of that commit [1], support for PFC is +suggested. However, having a compressed (1-byte) protocol field means +the subsequent PPP payload is shifted by one byte, causing 4-byte +misalignment for the network header and an unaligned access exception +on some architectures. + +The exception can be reproduced by sending a PPPoE PFC frame to an +ethernet interface of a MIPS board, with RPS enabled, even if no PPPoE +session is active on that interface: + +$ 0 : 00000000 80c40000 00000000 85144817 +$ 4 : 00000008 00000100 80a75758 81dc9bb8 +$ 8 : 00000010 8087ae2c 0000003d 00000000 +$12 : 000000e0 00000039 00000000 00000000 +$16 : 85043240 80a75758 81dc9bb8 00006488 +$20 : 0000002f 00000007 85144810 80a70000 +$24 : 81d1bda0 00000000 +$28 : 81dc8000 81dc9aa8 00000000 805ead08 +Hi : 00009d51 +Lo : 2163358a +epc : 805e91f0 __skb_flow_dissect+0x1b0/0x1b50 +ra : 805ead08 __skb_get_hash_net+0x74/0x12c +Status: 11000403 KERNEL EXL IE +Cause : 40800010 (ExcCode 04) +BadVA : 85144817 +PrId : 0001992f (MIPS 1004Kc) +Call Trace: +[<805e91f0>] __skb_flow_dissect+0x1b0/0x1b50 +[<805ead08>] __skb_get_hash_net+0x74/0x12c +[<805ef330>] get_rps_cpu+0x1b8/0x3fc +[<805fca70>] netif_receive_skb_list_internal+0x324/0x364 +[<805fd120>] napi_complete_done+0x68/0x2a4 +[<8058de5c>] mtk_napi_rx+0x228/0xfec +[<805fd398>] __napi_poll+0x3c/0x1c4 +[<805fd754>] napi_threaded_poll_loop+0x234/0x29c +[<805fd848>] napi_threaded_poll+0x8c/0xb0 +[<80053544>] kthread+0x104/0x12c +[<80002bd8>] ret_from_kernel_thread+0x14/0x1c + +Code: 02d51821 1060045b 00000000 <8c640000> 3084000f 2c820005 144001a2 00042080 8e220000 + +To reduce the attack surface and maintain performance, do not process +PPPoE PFC frames. + +[1] https://lore.kernel.org/r/20220630231016.GA392@debian.home +Fixes: 46126db9c861 ("flow_dissector: Add PPPoE dissectors") +Signed-off-by: Qingfang Deng +Link: https://patch.msgid.link/20260415022456.141758-1-qingfang.deng@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index c3d64e2d59295..86eb489ee76e0 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1229,16 +1229,13 @@ bool __skb_flow_dissect(const struct net *net, + break; + } + +- /* least significant bit of the most significant octet +- * indicates if protocol field was compressed ++ /* PFC (compressed 1-byte protocol) frames are not processed. ++ * A compressed protocol field has the least significant bit of ++ * the most significant octet set, which will fail the following ++ * ppp_proto_is_valid(), returning FLOW_DISSECT_RET_OUT_BAD. + */ + ppp_proto = ntohs(hdr->proto); +- if (ppp_proto & 0x0100) { +- ppp_proto = ppp_proto >> 8; +- nhoff += PPPOE_SES_HLEN - 1; +- } else { +- nhoff += PPPOE_SES_HLEN; +- } ++ nhoff += PPPOE_SES_HLEN; + + if (ppp_proto == PPP_IP) { + proto = htons(ETH_P_IP); +-- +2.53.0 + diff --git a/queue-5.10/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-5.10/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..a938596fc7 --- /dev/null +++ b/queue-5.10/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From b3730c05f738b031de6a6e7e8f83969f0b3386de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 7a8b05174ebf7..4d0f86c3ae703 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -215,16 +215,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -372,7 +370,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -397,7 +395,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -493,7 +491,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -504,7 +502,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-5.10/net-sched-taprio-fix-init-procedure.patch b/queue-5.10/net-sched-taprio-fix-init-procedure.patch new file mode 100644 index 0000000000..e9708d4efc --- /dev/null +++ b/queue-5.10/net-sched-taprio-fix-init-procedure.patch @@ -0,0 +1,40 @@ +From 1f445b9ecd97cd9d9ece722686008a595e4b2533 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Jul 2021 18:53:21 +0200 +Subject: net/sched: taprio: Fix init procedure + +From: Yannick Vignon + +[ Upstream commit ebca25ead0711729e0aeeec45062e7ac4df3e158 ] + +Commit 13511704f8d759 ("net: taprio offload: enforce qdisc to netdev queue mapping") +resulted in duplicate entries in the qdisc hash. +While this did not impact the overall operation of the qdisc and taprio +code paths, it did result in an infinite loop when dumping the qdisc +properties, at least on one target (NXP LS1028 ARDB). +Removing the duplicate call to qdisc_hash_add() solves the problem. + +Fixes: 13511704f8d759 ("net: taprio offload: enforce qdisc to netdev queue mapping") +Signed-off-by: Yannick Vignon +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/sched/sch_taprio.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index 85812bad227bc..50f430280337d 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -1723,8 +1723,6 @@ static void taprio_attach(struct Qdisc *sch) + if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { + qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; + old = dev_graft_qdisc(qdisc->dev_queue, qdisc); +- if (ntx < dev->real_num_tx_queues) +- qdisc_hash_add(qdisc, false); + } else { + old = dev_graft_qdisc(qdisc->dev_queue, sch); + qdisc_refcount_inc(sch); +-- +2.53.0 + diff --git a/queue-5.10/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch b/queue-5.10/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch new file mode 100644 index 0000000000..f1dcd5b4e2 --- /dev/null +++ b/queue-5.10/rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch @@ -0,0 +1,40 @@ +From b6b9c324aec63cb9e9df3f4581f0e9e84f223465 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Feb 2023 23:27:53 +0100 +Subject: rtc: allow rtc_read_alarm without read_alarm callback + +From: Alexandre Belloni + +[ Upstream commit a783c962619271a8b905efad1d89adfec11ae0c8 ] + +.read_alarm is not necessary to read the current alarm because it is +recorded in the aie_timer and so rtc_read_alarm() will never call +rtc_read_alarm_internal() which is the only function calling the callback. + +Reported-by: Zhipeng Wang +Reported-by: Marcel Ziswiler +Fixes: 7ae41220ef58 ("rtc: introduce features bitfield") +Tested-by: Philippe Schenker +Link: https://lore.kernel.org/r/20230214222754.582582-1-alexandre.belloni@bootlin.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/rtc/interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c +index 7df7457d7dc13..d35c46498629e 100644 +--- a/drivers/rtc/interface.c ++++ b/drivers/rtc/interface.c +@@ -393,7 +393,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + return err; + if (!rtc->ops) { + err = -ENODEV; +- } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) { ++ } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features)) { + err = -EINVAL; + } else { + memset(alarm, 0, sizeof(struct rtc_wkalrm)); +-- +2.53.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 18e3eb742b..8eef2d7c29 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -503,3 +503,10 @@ bareudp-fix-null-pointer-dereference-in-bareudp_fill.patch net-sched-sch_cake-annotate-data-races-in-cake_dump_.patch drm-amd-display-allow-dce-link-encoder-without-aux-r.patch drm-amd-display-read-edid-from-vbios-embedded-panel-.patch +btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch +net-sched-taprio-fix-init-procedure.patch +flow_dissector-do-not-dissect-pppoe-pfc-frames.patch +flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +rtc-allow-rtc_read_alarm-without-read_alarm-callback.patch +alarmtimer-check-rtc-features-instead-of-ops.patch diff --git a/queue-5.15/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch b/queue-5.15/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch new file mode 100644 index 0000000000..07ac85b6af --- /dev/null +++ b/queue-5.15/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch @@ -0,0 +1,75 @@ +From 160b8dfcc210c3e73a873d7180aaecf1dd89f390 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Apr 2026 16:58:56 +0100 +Subject: btrfs: tracepoints: fix sleep while in atomic context in + btrfs_sync_file() + +From: Filipe Manana + +[ Upstream commit c73370c677646e86fc4b1780fb07027bdf847375 ] + +The trace event btrfs_sync_file() is called in an atomic context (all trace +events are) and its call to dput(), which is needed due to the call to +dget_parent(), can sleep, triggering a kernel splat. + +This can be reproduced by enabling the trace event and running btrfs/056 +from fstests for example. The splat shown in dmesg is the following: + + [53.919] BUG: sleeping function called from invalid context at fs/dcache.c:970 + [53.947] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 32773, name: xfs_io + [53.988] preempt_count: 2, expected: 0 + [53.967] RCU nest depth: 0, expected: 0 + [53.943] Preemption disabled at: + [53.944] [<0000000000000000>] 0x0 + [54.078] CPU: 0 UID: 0 PID: 32773 Comm: xfs_io Tainted: G W 7.1.0-rc1-btrfs-next-232+ #1 PREEMPT(full) + [54.070] Tainted: [W]=WARN + [54.071] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 + [54.072] Call Trace: + [54.074] + [54.076] dump_stack_lvl+0x56/0x80 + [54.079] __might_resched.cold+0xd6/0x10f + [54.072] dput.part.0+0x24/0x110 + [54.078] trace_event_raw_event_btrfs_sync_file+0x75/0x140 [btrfs] + [54.089] btrfs_sync_file+0x1ed/0x530 [btrfs] + [54.087] ? __handle_mm_fault+0x8ae/0xed0 + [54.089] btrfs_do_write_iter+0x172/0x210 [btrfs] + [54.091] vfs_write+0x21f/0x450 + [54.094] __x64_sys_pwrite64+0x8d/0xc0 + [54.096] ? do_user_addr_fault+0x20c/0x670 + [54.099] do_syscall_64+0x60/0xf20 + [54.092] ? clear_bhb_loop+0x60/0xb0 + [54.094] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +So stop using dget_parent() and dput() and access the parent dentry +directly as dentry->d_parent. This is also what ext4 is doing in +its equivalent trace event ext4_sync_file_enter(). + +Fixes: a85b46db143f ("btrfs: tracepoints: get correct superblock from dentry in event btrfs_sync_file()") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + include/trace/events/btrfs.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h +index 058c85534f3f1..3c8bbe2a24a55 100644 +--- a/include/trace/events/btrfs.h ++++ b/include/trace/events/btrfs.h +@@ -697,10 +697,8 @@ TRACE_EVENT(btrfs_sync_file, + TP_fast_assign( + struct dentry *dentry = file_dentry(file); + struct inode *inode = file_inode(file); +- struct dentry *parent = dget_parent(dentry); +- struct inode *parent_inode = d_inode(parent); ++ struct inode *parent_inode = d_inode(dentry->d_parent); + +- dput(parent); + TP_fast_assign_fsid(btrfs_sb(inode->i_sb)); + __entry->ino = btrfs_ino(BTRFS_I(inode)); + __entry->parent = btrfs_ino(BTRFS_I(parent_inode)); +-- +2.53.0 + diff --git a/queue-5.15/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch b/queue-5.15/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch new file mode 100644 index 0000000000..94bec12a52 --- /dev/null +++ b/queue-5.15/flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch @@ -0,0 +1,60 @@ +From 4941746a00389260dd21ba6261b29245675bde0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 15:48:08 +0800 +Subject: flow_dissector: Do not count vlan tags inside tunnel payload + +From: Qingqing Yang + +[ Upstream commit 9f87eb4246994e32a4e4ea88476b20ab3b412840 ] + +We've met the problem that when there is a vlan tag inside +GRE encapsulation, the match of num_of_vlans fails. +It is caused by the vlan tag inside GRE payload has been +counted into num_of_vlans, which is not expected. + +One example packet is like this: +Ethernet II, Src: Broadcom_68:56:07 (00:10:18:68:56:07) + Dst: Broadcom_68:56:08 (00:10:18:68:56:08) +802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 100 +Internet Protocol Version 4, Src: 192.168.1.4, Dst: 192.168.1.200 +Generic Routing Encapsulation (Transparent Ethernet bridging) +Ethernet II, Src: Broadcom_68:58:07 (00:10:18:68:58:07) + Dst: Broadcom_68:58:08 (00:10:18:68:58:08) +802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 200 +... +It should match the (num_of_vlans 1) rule, but it matches +the (num_of_vlans 2) rule. + +The vlan tags inside the GRE or other tunnel encapsulated payload +should not be taken into num_of_vlans. +The fix is to stop counting the vlan number when the encapsulation +bit is set. + +Fixes: 34951fcf26c5 ("flow_dissector: Add number of vlan tags dissector") +Signed-off-by: Qingqing Yang +Reviewed-by: Boris Sukholitko +Link: https://lore.kernel.org/r/20220919074808.136640-1-qingqing.yang@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 7ab80767d94c3..db5677fbf81d3 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1180,8 +1180,8 @@ bool __skb_flow_dissect(const struct net *net, + nhoff += sizeof(*vlan); + } + +- if (dissector_uses_key(flow_dissector, +- FLOW_DISSECTOR_KEY_NUM_OF_VLANS)) { ++ if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_NUM_OF_VLANS) && ++ !(key_control->flags & FLOW_DIS_ENCAPSULATION)) { + struct flow_dissector_key_num_of_vlans *key_nvs; + + key_nvs = skb_flow_dissector_target(flow_dissector, +-- +2.53.0 + diff --git a/queue-5.15/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch b/queue-5.15/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch new file mode 100644 index 0000000000..0b2f0d77cf --- /dev/null +++ b/queue-5.15/flow_dissector-do-not-dissect-pppoe-pfc-frames.patch @@ -0,0 +1,97 @@ +From 16d8f6cdee2cad879807369d013bc511aae05c05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Apr 2026 10:24:50 +0800 +Subject: flow_dissector: do not dissect PPPoE PFC frames + +From: Qingfang Deng + +[ Upstream commit d6c19b31a3c1d519fabdcf0aa239e6b6109b9473 ] + +RFC 2516 Section 7 states that Protocol Field Compression (PFC) is NOT +RECOMMENDED for PPPoE. In practice, pppd does not support negotiating +PFC for PPPoE sessions, and the flow dissector driver has assumed an +uncompressed frame until the blamed commit. + +During the review process of that commit [1], support for PFC is +suggested. However, having a compressed (1-byte) protocol field means +the subsequent PPP payload is shifted by one byte, causing 4-byte +misalignment for the network header and an unaligned access exception +on some architectures. + +The exception can be reproduced by sending a PPPoE PFC frame to an +ethernet interface of a MIPS board, with RPS enabled, even if no PPPoE +session is active on that interface: + +$ 0 : 00000000 80c40000 00000000 85144817 +$ 4 : 00000008 00000100 80a75758 81dc9bb8 +$ 8 : 00000010 8087ae2c 0000003d 00000000 +$12 : 000000e0 00000039 00000000 00000000 +$16 : 85043240 80a75758 81dc9bb8 00006488 +$20 : 0000002f 00000007 85144810 80a70000 +$24 : 81d1bda0 00000000 +$28 : 81dc8000 81dc9aa8 00000000 805ead08 +Hi : 00009d51 +Lo : 2163358a +epc : 805e91f0 __skb_flow_dissect+0x1b0/0x1b50 +ra : 805ead08 __skb_get_hash_net+0x74/0x12c +Status: 11000403 KERNEL EXL IE +Cause : 40800010 (ExcCode 04) +BadVA : 85144817 +PrId : 0001992f (MIPS 1004Kc) +Call Trace: +[<805e91f0>] __skb_flow_dissect+0x1b0/0x1b50 +[<805ead08>] __skb_get_hash_net+0x74/0x12c +[<805ef330>] get_rps_cpu+0x1b8/0x3fc +[<805fca70>] netif_receive_skb_list_internal+0x324/0x364 +[<805fd120>] napi_complete_done+0x68/0x2a4 +[<8058de5c>] mtk_napi_rx+0x228/0xfec +[<805fd398>] __napi_poll+0x3c/0x1c4 +[<805fd754>] napi_threaded_poll_loop+0x234/0x29c +[<805fd848>] napi_threaded_poll+0x8c/0xb0 +[<80053544>] kthread+0x104/0x12c +[<80002bd8>] ret_from_kernel_thread+0x14/0x1c + +Code: 02d51821 1060045b 00000000 <8c640000> 3084000f 2c820005 144001a2 00042080 8e220000 + +To reduce the attack surface and maintain performance, do not process +PPPoE PFC frames. + +[1] https://lore.kernel.org/r/20220630231016.GA392@debian.home +Fixes: 46126db9c861 ("flow_dissector: Add PPPoE dissectors") +Signed-off-by: Qingfang Deng +Link: https://patch.msgid.link/20260415022456.141758-1-qingfang.deng@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index 164de39fd262c..7ab80767d94c3 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1239,16 +1239,13 @@ bool __skb_flow_dissect(const struct net *net, + break; + } + +- /* least significant bit of the most significant octet +- * indicates if protocol field was compressed ++ /* PFC (compressed 1-byte protocol) frames are not processed. ++ * A compressed protocol field has the least significant bit of ++ * the most significant octet set, which will fail the following ++ * ppp_proto_is_valid(), returning FLOW_DISSECT_RET_OUT_BAD. + */ + ppp_proto = ntohs(hdr->proto); +- if (ppp_proto & 0x0100) { +- ppp_proto = ppp_proto >> 8; +- nhoff += PPPOE_SES_HLEN - 1; +- } else { +- nhoff += PPPOE_SES_HLEN; +- } ++ nhoff += PPPOE_SES_HLEN; + + if (ppp_proto == PPP_IP) { + proto = htons(ETH_P_IP); +-- +2.53.0 + diff --git a/queue-5.15/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-5.15/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..adbd2179b5 --- /dev/null +++ b/queue-5.15/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 69082411faab4a72738e86653cfed0078b5e1743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 1e4c84535c0e3..ad0d8c892f120 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -215,16 +215,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -372,7 +370,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -397,7 +395,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -493,7 +491,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -504,7 +502,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 5e3598209b..39567e8bee 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -653,3 +653,9 @@ alsa-hda-conexant-renaming-the-codec-with-device-id-.patch alsa-hda-conexant-fix-missing-error-check-for-jack-d.patch drm-amd-display-allow-dce-link-encoder-without-aux-r.patch drm-amd-display-read-edid-from-vbios-embedded-panel-.patch +btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch +sunrpc-check-if-the-xprt-is-connected-before-handlin.patch +sunrpc-do-not-dereference-non-socket-transports-in-s.patch +flow_dissector-do-not-dissect-pppoe-pfc-frames.patch +flow_dissector-do-not-count-vlan-tags-inside-tunnel-.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch diff --git a/queue-5.15/sunrpc-check-if-the-xprt-is-connected-before-handlin.patch b/queue-5.15/sunrpc-check-if-the-xprt-is-connected-before-handlin.patch new file mode 100644 index 0000000000..45aab497ea --- /dev/null +++ b/queue-5.15/sunrpc-check-if-the-xprt-is-connected-before-handlin.patch @@ -0,0 +1,56 @@ +From be4b7597b21e8cebbb09ee68df1eb2d6b96b709f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Oct 2021 15:17:41 -0400 +Subject: SUNRPC: Check if the xprt is connected before handling sysfs reads + +From: Anna Schumaker + +[ Upstream commit 17f09d3f619a7ad2d2b021b4e5246f08225b1b0f ] + +xprts don't immediately reconnect when changing the "dstaddr" property, +instead this gets handled the next time an operation uses the transport. +This could lead to NULL pointer dereferences when trying to read sysfs +files between the disconnect and reconnect operations. Fix this by +returning an error if the xprt is not connected. + +Signed-off-by: Anna Schumaker +Signed-off-by: Trond Myklebust +Stable-dep-of: 421ab1be43bd ("SUNRPC: Do not dereference non-socket transports in sysfs") +Signed-off-by: Sasha Levin +--- + net/sunrpc/sysfs.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c +index 83ba1f2adf624..33e8fb85ce4f4 100644 +--- a/net/sunrpc/sysfs.c ++++ b/net/sunrpc/sysfs.c +@@ -109,8 +109,10 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj, + struct sock_xprt *sock; + ssize_t ret = -1; + +- if (!xprt) +- return 0; ++ if (!xprt || !xprt_connected(xprt)) { ++ xprt_put(xprt); ++ return -ENOTCONN; ++ } + + sock = container_of(xprt, struct sock_xprt, xprt); + mutex_lock(&sock->recv_mutex); +@@ -132,8 +134,10 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, + struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj); + ssize_t ret; + +- if (!xprt) +- return 0; ++ if (!xprt || !xprt_connected(xprt)) { ++ xprt_put(xprt); ++ return -ENOTCONN; ++ } + + ret = sprintf(buf, "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n" + "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n" +-- +2.53.0 + diff --git a/queue-5.15/sunrpc-do-not-dereference-non-socket-transports-in-s.patch b/queue-5.15/sunrpc-do-not-dereference-non-socket-transports-in-s.patch new file mode 100644 index 0000000000..94d90dc18a --- /dev/null +++ b/queue-5.15/sunrpc-do-not-dereference-non-socket-transports-in-s.patch @@ -0,0 +1,224 @@ +From edc983b53cbffe6ae0697b6d1056fb6cb2cfea0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Mar 2022 10:37:31 -0400 +Subject: SUNRPC: Do not dereference non-socket transports in sysfs + +From: Trond Myklebust + +[ Upstream commit 421ab1be43bd015ffe744f4ea25df4f19d1ce6fe ] + +Do not cast the struct xprt to a sock_xprt unless we know it is a UDP or +TCP transport. Otherwise the call to lock the mutex will scribble over +whatever structure is actually there. This has been seen to cause hard +system lockups when the underlying transport was RDMA. + +Fixes: b49ea673e119 ("SUNRPC: lock against ->sock changing during sysfs read") +Cc: stable@vger.kernel.org +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/xprt.h | 3 ++ + include/linux/sunrpc/xprtsock.h | 1 - + net/sunrpc/sysfs.c | 55 ++++++++++++++++----------------- + net/sunrpc/xprtsock.c | 26 ++++++++++++++-- + 4 files changed, 54 insertions(+), 31 deletions(-) + +diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h +index 955ea4d7af0b2..eef5e87c03b43 100644 +--- a/include/linux/sunrpc/xprt.h ++++ b/include/linux/sunrpc/xprt.h +@@ -139,6 +139,9 @@ struct rpc_xprt_ops { + void (*rpcbind)(struct rpc_task *task); + void (*set_port)(struct rpc_xprt *xprt, unsigned short port); + void (*connect)(struct rpc_xprt *xprt, struct rpc_task *task); ++ int (*get_srcaddr)(struct rpc_xprt *xprt, char *buf, ++ size_t buflen); ++ unsigned short (*get_srcport)(struct rpc_xprt *xprt); + int (*buf_alloc)(struct rpc_task *task); + void (*buf_free)(struct rpc_task *task); + void (*prepare_request)(struct rpc_rqst *req); +diff --git a/include/linux/sunrpc/xprtsock.h b/include/linux/sunrpc/xprtsock.h +index 3eb0079669c50..38284f25eddfd 100644 +--- a/include/linux/sunrpc/xprtsock.h ++++ b/include/linux/sunrpc/xprtsock.h +@@ -10,7 +10,6 @@ + + int init_socket_xprt(void); + void cleanup_socket_xprt(void); +-unsigned short get_srcport(struct rpc_xprt *); + + #define RPC_MIN_RESVPORT (1U) + #define RPC_MAX_RESVPORT (65535U) +diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c +index 33e8fb85ce4f4..e643dd8748a29 100644 +--- a/net/sunrpc/sysfs.c ++++ b/net/sunrpc/sysfs.c +@@ -97,7 +97,7 @@ static ssize_t rpc_sysfs_xprt_dstaddr_show(struct kobject *kobj, + return 0; + ret = sprintf(buf, "%s\n", xprt->address_strings[RPC_DISPLAY_ADDR]); + xprt_put(xprt); +- return ret + 1; ++ return ret; + } + + static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj, +@@ -105,33 +105,31 @@ static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj, + char *buf) + { + struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj); +- struct sockaddr_storage saddr; +- struct sock_xprt *sock; +- ssize_t ret = -1; ++ size_t buflen = PAGE_SIZE; ++ ssize_t ret = -ENOTSOCK; + + if (!xprt || !xprt_connected(xprt)) { +- xprt_put(xprt); +- return -ENOTCONN; ++ ret = -ENOTCONN; ++ } else if (xprt->ops->get_srcaddr) { ++ ret = xprt->ops->get_srcaddr(xprt, buf, buflen); ++ if (ret > 0) { ++ if (ret < buflen - 1) { ++ buf[ret] = '\n'; ++ ret++; ++ buf[ret] = '\0'; ++ } ++ } + } +- +- sock = container_of(xprt, struct sock_xprt, xprt); +- mutex_lock(&sock->recv_mutex); +- if (sock->sock == NULL || +- kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0) +- goto out; +- +- ret = sprintf(buf, "%pISc\n", &saddr); +-out: +- mutex_unlock(&sock->recv_mutex); + xprt_put(xprt); +- return ret + 1; ++ return ret; + } + + static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, +- struct kobj_attribute *attr, +- char *buf) ++ struct kobj_attribute *attr, char *buf) + { + struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj); ++ unsigned short srcport = 0; ++ size_t buflen = PAGE_SIZE; + ssize_t ret; + + if (!xprt || !xprt_connected(xprt)) { +@@ -139,7 +137,11 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, + return -ENOTCONN; + } + +- ret = sprintf(buf, "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n" ++ if (xprt->ops->get_srcport) ++ srcport = xprt->ops->get_srcport(xprt); ++ ++ ret = snprintf(buf, buflen, ++ "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n" + "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n" + "binding_q_len=%u\nsending_q_len=%u\npending_q_len=%u\n" + "backlog_q_len=%u\nmain_xprt=%d\nsrc_port=%u\n" +@@ -147,14 +149,11 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, + xprt->last_used, xprt->cong, xprt->cwnd, xprt->max_reqs, + xprt->min_reqs, xprt->num_reqs, xprt->binding.qlen, + xprt->sending.qlen, xprt->pending.qlen, +- xprt->backlog.qlen, xprt->main, +- (xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) ? +- get_srcport(xprt) : 0, ++ xprt->backlog.qlen, xprt->main, srcport, + atomic_long_read(&xprt->queuelen), +- (xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) ? +- xprt->address_strings[RPC_DISPLAY_PORT] : "0"); ++ xprt->address_strings[RPC_DISPLAY_PORT]); + xprt_put(xprt); +- return ret + 1; ++ return ret; + } + + static ssize_t rpc_sysfs_xprt_state_show(struct kobject *kobj, +@@ -201,7 +200,7 @@ static ssize_t rpc_sysfs_xprt_state_show(struct kobject *kobj, + } + + xprt_put(xprt); +- return ret + 1; ++ return ret; + } + + static ssize_t rpc_sysfs_xprt_switch_info_show(struct kobject *kobj, +@@ -220,7 +219,7 @@ static ssize_t rpc_sysfs_xprt_switch_info_show(struct kobject *kobj, + xprt_switch->xps_nunique_destaddr_xprts, + atomic_long_read(&xprt_switch->xps_queuelen)); + xprt_switch_put(xprt_switch); +- return ret + 1; ++ return ret; + } + + static ssize_t rpc_sysfs_xprt_dstaddr_store(struct kobject *kobj, +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 07acc6845ce29..a829da4bbb09e 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1677,7 +1677,7 @@ static int xs_get_srcport(struct sock_xprt *transport) + return port; + } + +-unsigned short get_srcport(struct rpc_xprt *xprt) ++static unsigned short xs_sock_srcport(struct rpc_xprt *xprt) + { + struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); + unsigned short ret = 0; +@@ -1687,7 +1687,25 @@ unsigned short get_srcport(struct rpc_xprt *xprt) + mutex_unlock(&sock->recv_mutex); + return ret; + } +-EXPORT_SYMBOL(get_srcport); ++ ++static int xs_sock_srcaddr(struct rpc_xprt *xprt, char *buf, size_t buflen) ++{ ++ struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); ++ union { ++ struct sockaddr sa; ++ struct sockaddr_storage st; ++ } saddr; ++ int ret = -ENOTCONN; ++ ++ mutex_lock(&sock->recv_mutex); ++ if (sock->sock) { ++ ret = kernel_getsockname(sock->sock, &saddr.sa); ++ if (ret >= 0) ++ ret = snprintf(buf, buflen, "%pISc", &saddr.sa); ++ } ++ mutex_unlock(&sock->recv_mutex); ++ return ret; ++} + + static unsigned short xs_next_srcport(struct sock_xprt *transport, unsigned short port) + { +@@ -2678,6 +2696,8 @@ static const struct rpc_xprt_ops xs_udp_ops = { + .rpcbind = rpcb_getport_async, + .set_port = xs_set_port, + .connect = xs_connect, ++ .get_srcaddr = xs_sock_srcaddr, ++ .get_srcport = xs_sock_srcport, + .buf_alloc = rpc_malloc, + .buf_free = rpc_free, + .send_request = xs_udp_send_request, +@@ -2700,6 +2720,8 @@ static const struct rpc_xprt_ops xs_tcp_ops = { + .rpcbind = rpcb_getport_async, + .set_port = xs_set_port, + .connect = xs_connect, ++ .get_srcaddr = xs_sock_srcaddr, ++ .get_srcport = xs_sock_srcport, + .buf_alloc = rpc_malloc, + .buf_free = rpc_free, + .prepare_request = xs_stream_prepare_request, +-- +2.53.0 + diff --git a/queue-6.1/alsa-core-serialize-deferred-fasync-state-checks.patch b/queue-6.1/alsa-core-serialize-deferred-fasync-state-checks.patch new file mode 100644 index 0000000000..3a72e979d6 --- /dev/null +++ b/queue-6.1/alsa-core-serialize-deferred-fasync-state-checks.patch @@ -0,0 +1,68 @@ +From fb55ff48611acb6622c12922b1eea543052160a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 May 2026 00:34:47 -0300 +Subject: ALSA: core: Serialize deferred fasync state checks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Cássio Gabriel + +[ Upstream commit 5337213381df578058e2e41da93cbd0e4639935f ] + +snd_fasync_helper() updates fasync->on under snd_fasync_lock, and +snd_fasync_work_fn() now also evaluates fasync->on under the same +lock. snd_kill_fasync() still tests the flag before taking the lock, +leaving an unsynchronized read against FASYNC enable/disable updates. + +Move the enabled-state check into the locked section. + +Also clear fasync->on under snd_fasync_lock in snd_fasync_free() +before unlinking the pending entry. Together with the locked sender-side +check, this publishes teardown before flushing the deferred work and +prevents a racing sender from requeueing the entry after free has +started. + +Fixes: ef34a0ae7a26 ("ALSA: core: Add async signal helpers") +Fixes: 8146cd333d23 ("ALSA: core: Fix potential data race at fasync handling") +Cc: stable@vger.kernel.org +Signed-off-by: Cássio Gabriel +Link: https://patch.msgid.link/20260506-alsa-core-fasync-on-lock-v1-1-ea48c77d6ca4@gmail.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/core/misc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/sound/core/misc.c b/sound/core/misc.c +index 918d59a541c82..fd891a3ceb963 100644 +--- a/sound/core/misc.c ++++ b/sound/core/misc.c +@@ -219,9 +219,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper); + + void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll) + { +- if (!fasync || !fasync->on) ++ if (!fasync) + return; + guard(spinlock_irqsave)(&snd_fasync_lock); ++ if (!fasync->on) ++ return; + fasync->signal = signal; + fasync->poll = poll; + list_move(&fasync->list, &snd_fasync_list); +@@ -234,8 +236,10 @@ void snd_fasync_free(struct snd_fasync *fasync) + if (!fasync) + return; + +- scoped_guard(spinlock_irq, &snd_fasync_lock) ++ scoped_guard(spinlock_irq, &snd_fasync_lock) { ++ fasync->on = 0; + list_del_init(&fasync->list); ++ } + + flush_work(&snd_fasync_work); + kfree(fasync); +-- +2.53.0 + diff --git a/queue-6.1/alsa-misc-use-guard-for-spin-locks.patch b/queue-6.1/alsa-misc-use-guard-for-spin-locks.patch new file mode 100644 index 0000000000..bd73a7556d --- /dev/null +++ b/queue-6.1/alsa-misc-use-guard-for-spin-locks.patch @@ -0,0 +1,74 @@ +From 290aaf249358e3d022e6933dce183c2da35c514d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Aug 2025 17:13:33 +0200 +Subject: ALSA: misc: Use guard() for spin locks + +From: Takashi Iwai + +[ Upstream commit b8e1684163ae52db90f428965bd9aaff7205c02e ] + +Clean up the code using guard() for spin locks. + +Merely code refactoring, and no behavior change. + +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20250829151335.7342-20-tiwai@suse.de +Stable-dep-of: 5337213381df ("ALSA: core: Serialize deferred fasync state checks") +Signed-off-by: Sasha Levin +--- + sound/core/misc.c | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/sound/core/misc.c b/sound/core/misc.c +index 856edaa1dedbc..918d59a541c82 100644 +--- a/sound/core/misc.c ++++ b/sound/core/misc.c +@@ -202,35 +202,30 @@ int snd_fasync_helper(int fd, struct file *file, int on, + INIT_LIST_HEAD(&fasync->list); + } + +- spin_lock_irq(&snd_fasync_lock); +- if (*fasyncp) { +- kfree(fasync); +- fasync = *fasyncp; +- } else { +- if (!fasync) { +- spin_unlock_irq(&snd_fasync_lock); +- return 0; ++ scoped_guard(spinlock_irq, &snd_fasync_lock) { ++ if (*fasyncp) { ++ kfree(fasync); ++ fasync = *fasyncp; ++ } else { ++ if (!fasync) ++ return 0; ++ *fasyncp = fasync; + } +- *fasyncp = fasync; ++ fasync->on = on; + } +- fasync->on = on; +- spin_unlock_irq(&snd_fasync_lock); + return fasync_helper(fd, file, on, &fasync->fasync); + } + EXPORT_SYMBOL_GPL(snd_fasync_helper); + + void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll) + { +- unsigned long flags; +- + if (!fasync || !fasync->on) + return; +- spin_lock_irqsave(&snd_fasync_lock, flags); ++ guard(spinlock_irqsave)(&snd_fasync_lock); + fasync->signal = signal; + fasync->poll = poll; + list_move(&fasync->list, &snd_fasync_list); + schedule_work(&snd_fasync_work); +- spin_unlock_irqrestore(&snd_fasync_lock, flags); + } + EXPORT_SYMBOL_GPL(snd_kill_fasync); + +-- +2.53.0 + diff --git a/queue-6.1/asoc-sof-pcm-clear-the-susbstream-pointer-to-null-on.patch b/queue-6.1/asoc-sof-pcm-clear-the-susbstream-pointer-to-null-on.patch new file mode 100644 index 0000000000..e6b31c2320 --- /dev/null +++ b/queue-6.1/asoc-sof-pcm-clear-the-susbstream-pointer-to-null-on.patch @@ -0,0 +1,48 @@ +From f041a559787190a4078575490be2d12812d80b18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:52:32 +0200 +Subject: ASoC: SOF: pcm: Clear the susbstream pointer to NULL on close + +From: Peter Ujfalusi + +[ Upstream commit 46c7b901e2a03536df5a3cb40b3b26e2be505df6 ] + +The spcm->stream[substream->stream].substream is set during open and was +left untouched. After the first PCM stream it will never be NULL and we +have code which checks for substream NULLity as indication if the stream is +active or not. +For the compressed cstream pointer the same has been done, this change will +correct the handling of PCM streams. + +Fixes: 090349a9feba ("ASoC: SOF: Add support for compress API for stream data/offset") +Cc: stable@vger.kernel.org +Reported-by: Curtis Malainey +Closes: https://github.com/thesofproject/linux/pull/5214 +Signed-off-by: Peter Ujfalusi +Reviewed-by: Daniel Baluta +Reviewed-by: Ranjani Sridharan +Reviewed-by: Bard Liao +Reviewed-by: Curtis Malainey +Link: https://patch.msgid.link/20250205135232.19762-3-peter.ujfalusi@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/pcm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c +index be6f38af37b5d..c2cb005285e3f 100644 +--- a/sound/soc/sof/pcm.c ++++ b/sound/soc/sof/pcm.c +@@ -484,6 +484,8 @@ static int sof_pcm_close(struct snd_soc_component *component, + */ + } + ++ spcm->stream[substream->stream].substream = NULL; ++ + return 0; + } + +-- +2.53.0 + diff --git a/queue-6.1/asoc-sof-stream-ipc-check-for-cstream-nullity-in-sof.patch b/queue-6.1/asoc-sof-stream-ipc-check-for-cstream-nullity-in-sof.patch new file mode 100644 index 0000000000..f8cfda25c4 --- /dev/null +++ b/queue-6.1/asoc-sof-stream-ipc-check-for-cstream-nullity-in-sof.patch @@ -0,0 +1,58 @@ +From 9e5414ebcfc3f366fa491f92ed608fd95e6aae17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:52:31 +0200 +Subject: ASoC: SOF: stream-ipc: Check for cstream nullity in + sof_ipc_msg_data() + +From: Peter Ujfalusi + +[ Upstream commit d8d99c3b5c485f339864aeaa29f76269cc0ea975 ] + +The nullity of sps->cstream should be checked similarly as it is done in +sof_set_stream_data_offset() function. +Assuming that it is not NULL if sps->stream is NULL is incorrect and can +lead to NULL pointer dereference. + +Fixes: 090349a9feba ("ASoC: SOF: Add support for compress API for stream data/offset") +Cc: stable@vger.kernel.org +Reported-by: Curtis Malainey +Closes: https://github.com/thesofproject/linux/pull/5214 +Signed-off-by: Peter Ujfalusi +Reviewed-by: Daniel Baluta +Reviewed-by: Ranjani Sridharan +Reviewed-by: Bard Liao +Reviewed-by: Curtis Malainey +Link: https://patch.msgid.link/20250205135232.19762-2-peter.ujfalusi@linux.intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sof/stream-ipc.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c +index 216b454f6b94e..3edcb0ea38488 100644 +--- a/sound/soc/sof/stream-ipc.c ++++ b/sound/soc/sof/stream-ipc.c +@@ -43,7 +43,7 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev, + return -ESTRPIPE; + + posn_offset = stream->posn_offset; +- } else { ++ } else if (sps->cstream) { + + struct sof_compr_stream *sstream = sps->cstream->runtime->private_data; + +@@ -51,6 +51,10 @@ int sof_ipc_msg_data(struct snd_sof_dev *sdev, + return -ESTRPIPE; + + posn_offset = sstream->posn_offset; ++ ++ } else { ++ dev_err(sdev->dev, "%s: No stream opened\n", __func__); ++ return -EINVAL; + } + + snd_sof_dsp_mailbox_read(sdev, posn_offset, p, sz); +-- +2.53.0 + diff --git a/queue-6.1/bonding-fix-null-pointer-dereference-in-actor_port_p.patch b/queue-6.1/bonding-fix-null-pointer-dereference-in-actor_port_p.patch new file mode 100644 index 0000000000..1f185c39f9 --- /dev/null +++ b/queue-6.1/bonding-fix-null-pointer-dereference-in-actor_port_p.patch @@ -0,0 +1,65 @@ +From 90f6b6719c13420e9895e98a60bf4e99efbfeee1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 07:26:20 +0000 +Subject: bonding: fix NULL pointer dereference in actor_port_prio setting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hangbin Liu + +[ Upstream commit 067bf016e99ad72aa4ff869d6dec1fd62a9c6202 ] + +Liang reported an issue where setting a slave’s actor_port_prio to +predefined values such as 0, 255, or 65535 would cause a system crash. + +The problem occurs because in bond_opt_parse(), when the provided value +matches a predefined table entry, the function returns that table entry, +which does not contain slave information. Later, in +bond_option_actor_port_prio_set(), calling bond_slave_get_rtnl() leads +to a NULL pointer dereference. + +Since actor_port_prio is defined as a u16 and initialized to the default +value of 255 in ad_initialize_port(), there is no need for the +bond_actor_port_prio_tbl. Using the BOND_OPTFLAG_RAWVAL flag is sufficient. + +Fixes: 6b6dc81ee7e8 ("bonding: add support for per-port LACP actor priority") +Reported-by: Liang Li +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251105072620.164841-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_options.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index 2991290f450ee..40731d180bb50 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -225,13 +225,6 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = { + { NULL, -1, 0}, + }; + +-static const struct bond_opt_value bond_actor_port_prio_tbl[] = { +- { "minval", 0, BOND_VALFLAG_MIN}, +- { "maxval", 65535, BOND_VALFLAG_MAX}, +- { "default", 255, BOND_VALFLAG_DEFAULT}, +- { NULL, -1, 0}, +-}; +- + static const struct bond_opt_value bond_ad_user_port_key_tbl[] = { + { "minval", 0, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, + { "maxval", 1023, BOND_VALFLAG_MAX}, +@@ -497,7 +490,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { + .id = BOND_OPT_ACTOR_PORT_PRIO, + .name = "actor_port_prio", + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), +- .values = bond_actor_port_prio_tbl, ++ .flags = BOND_OPTFLAG_RAWVAL, + .set = bond_option_actor_port_prio_set, + }, + [BOND_OPT_AD_ACTOR_SYSTEM] = { +-- +2.53.0 + diff --git a/queue-6.1/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch b/queue-6.1/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch new file mode 100644 index 0000000000..e45609e5cc --- /dev/null +++ b/queue-6.1/btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch @@ -0,0 +1,75 @@ +From 800adc1890943c53c45addb594ad32efe4c0835e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Apr 2026 16:58:56 +0100 +Subject: btrfs: tracepoints: fix sleep while in atomic context in + btrfs_sync_file() + +From: Filipe Manana + +[ Upstream commit c73370c677646e86fc4b1780fb07027bdf847375 ] + +The trace event btrfs_sync_file() is called in an atomic context (all trace +events are) and its call to dput(), which is needed due to the call to +dget_parent(), can sleep, triggering a kernel splat. + +This can be reproduced by enabling the trace event and running btrfs/056 +from fstests for example. The splat shown in dmesg is the following: + + [53.919] BUG: sleeping function called from invalid context at fs/dcache.c:970 + [53.947] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 32773, name: xfs_io + [53.988] preempt_count: 2, expected: 0 + [53.967] RCU nest depth: 0, expected: 0 + [53.943] Preemption disabled at: + [53.944] [<0000000000000000>] 0x0 + [54.078] CPU: 0 UID: 0 PID: 32773 Comm: xfs_io Tainted: G W 7.1.0-rc1-btrfs-next-232+ #1 PREEMPT(full) + [54.070] Tainted: [W]=WARN + [54.071] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014 + [54.072] Call Trace: + [54.074] + [54.076] dump_stack_lvl+0x56/0x80 + [54.079] __might_resched.cold+0xd6/0x10f + [54.072] dput.part.0+0x24/0x110 + [54.078] trace_event_raw_event_btrfs_sync_file+0x75/0x140 [btrfs] + [54.089] btrfs_sync_file+0x1ed/0x530 [btrfs] + [54.087] ? __handle_mm_fault+0x8ae/0xed0 + [54.089] btrfs_do_write_iter+0x172/0x210 [btrfs] + [54.091] vfs_write+0x21f/0x450 + [54.094] __x64_sys_pwrite64+0x8d/0xc0 + [54.096] ? do_user_addr_fault+0x20c/0x670 + [54.099] do_syscall_64+0x60/0xf20 + [54.092] ? clear_bhb_loop+0x60/0xb0 + [54.094] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +So stop using dget_parent() and dput() and access the parent dentry +directly as dentry->d_parent. This is also what ext4 is doing in +its equivalent trace event ext4_sync_file_enter(). + +Fixes: a85b46db143f ("btrfs: tracepoints: get correct superblock from dentry in event btrfs_sync_file()") +Reviewed-by: Boris Burkov +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + include/trace/events/btrfs.h | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h +index 8054ce54807de..b2b41b98ec6d0 100644 +--- a/include/trace/events/btrfs.h ++++ b/include/trace/events/btrfs.h +@@ -762,10 +762,8 @@ TRACE_EVENT(btrfs_sync_file, + TP_fast_assign( + struct dentry *dentry = file_dentry(file); + struct inode *inode = file_inode(file); +- struct dentry *parent = dget_parent(dentry); +- struct inode *parent_inode = d_inode(parent); ++ struct inode *parent_inode = d_inode(dentry->d_parent); + +- dput(parent); + TP_fast_assign_fsid(btrfs_sb(inode->i_sb)); + __entry->ino = btrfs_ino(BTRFS_I(inode)); + __entry->parent = btrfs_ino(BTRFS_I(parent_inode)); +-- +2.53.0 + diff --git a/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-s.patch b/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-s.patch new file mode 100644 index 0000000000..a5fe307a2c --- /dev/null +++ b/queue-6.1/mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-s.patch @@ -0,0 +1,48 @@ +From c35738b5443f3d7119a52fe28bcd96e29e4ecc5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Apr 2023 15:17:46 +0900 +Subject: mtd: spi-nor: spansion: Enable JFFS2 write buffer for S25FS256T + +From: Takahiro Kuwano + +[ Upstream commit a9180c298d3527f43563d02a62cb9e7e145642c6 ] + +Infineon(Cypress) SEMPER NOR flash family has on-die ECC and its program +granularity is 16-byte ECC data unit size. JFFS2 supports write buffer +mode for ECC'd NOR flash. Provide a way to clear the MTD_BIT_WRITEABLE +flag in order to enable JFFS2 write buffer mode support. Drop the +comment as the same info is now specified in cypress_nor_ecc_init(). + +Fixes: 6afcc84080c4 ("mtd: spi-nor: spansion: Add support for Infineon S25FS256T") +Suggested-by: Tudor Ambarus +Signed-off-by: Takahiro Kuwano +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/641bfb26c6e059915ae920117b7ec278df1a6f0a.1680760742.git.Takahiro.Kuwano@infineon.com +Signed-off-by: Tudor Ambarus +Signed-off-by: Sasha Levin +--- + drivers/mtd/spi-nor/spansion.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c +index af97e3741f987..cd2d6a95d66e1 100644 +--- a/drivers/mtd/spi-nor/spansion.c ++++ b/drivers/mtd/spi-nor/spansion.c +@@ -273,13 +273,7 @@ static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor) + + static void s25fs256t_late_init(struct spi_nor *nor) + { +- /* +- * Programming is supported only in 16-byte ECC data unit granularity. +- * Byte-programming, bit-walking, or multiple program operations to the +- * same ECC data unit without an erase are not allowed. See chapter +- * 5.3.1 and 5.6 in the datasheet. +- */ +- nor->params->writesize = 16; ++ cypress_nor_ecc_init(nor); + } + + static struct spi_nor_fixups s25fs256t_fixups = { +-- +2.53.0 + diff --git a/queue-6.1/net-bcmgenet-fix-leaking-free_bds.patch b/queue-6.1/net-bcmgenet-fix-leaking-free_bds.patch new file mode 100644 index 0000000000..504fcead1a --- /dev/null +++ b/queue-6.1/net-bcmgenet-fix-leaking-free_bds.patch @@ -0,0 +1,49 @@ +From 18acc408600f105ce5bc3f005503753400b54137 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Apr 2026 10:57:55 -0700 +Subject: net: bcmgenet: fix leaking free_bds + +From: Justin Chen + +[ Upstream commit 3f3168300efb839028328d720ab3962f91d6a0d0 ] + +While reclaiming the tx queue we fast forward the write pointer to +drop any data in flight. These dropped frames are not added back +to the pool of free bds. We also need to tell the netdev that we +are dropping said data. + +Fixes: f1bacae8b655 ("net: bcmgenet: support reclaiming unsent Tx packets") +Signed-off-by: Justin Chen +Reviewed-by: Florian Fainelli +Reviewed-by: Nicolai Buchwitz +Tested-by: Nicolai Buchwitz +Link: https://patch.msgid.link/20260406175756.134567-3-justin.chen@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 64bc7b3afb514..cc7bcd0cc7ba8 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1937,6 +1937,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + drop = (ring->prod_index - ring->c_index) & DMA_C_INDEX_MASK; + released += drop; + ring->prod_index = ring->c_index & DMA_C_INDEX_MASK; ++ ring->free_bds += drop; + while (drop--) { + cb_ptr = bcmgenet_put_txcb(priv, ring); + skb = cb_ptr->skb; +@@ -1948,6 +1949,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + } + if (skb) + dev_consume_skb_any(skb); ++ netdev_tx_reset_queue(netdev_get_tx_queue(dev, ring->index)); + bcmgenet_tdma_ring_writel(priv, ring->index, + ring->prod_index, TDMA_PROD_INDEX); + wr_ptr = ring->write_ptr * WORDS_PER_BD(priv); +-- +2.53.0 + diff --git a/queue-6.1/net-bcmgenet-initialize-u64-stats-seq-counter.patch b/queue-6.1/net-bcmgenet-initialize-u64-stats-seq-counter.patch new file mode 100644 index 0000000000..426ea81503 --- /dev/null +++ b/queue-6.1/net-bcmgenet-initialize-u64-stats-seq-counter.patch @@ -0,0 +1,82 @@ +From 4ac731165cf2c84eab93ac422f53cc5e566c6816 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Jul 2025 18:24:17 +0900 +Subject: net: bcmgenet: Initialize u64 stats seq counter + +From: Ryo Takakura + +[ Upstream commit ffc2c8c4a714df53a715827d6334ab9474424f6a ] + +Initialize u64 stats as it uses seq counter on 32bit machines +as suggested by lockdep below. + +[ 1.830953][ T1] INFO: trying to register non-static key. +[ 1.830993][ T1] The code is fine but needs lockdep annotation, or maybe +[ 1.831027][ T1] you didn't initialize this object before use? +[ 1.831057][ T1] turning off the locking correctness validator. +[ 1.831090][ T1] CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 6.16.0-rc2-v7l+ #1 PREEMPT +[ 1.831097][ T1] Tainted: [W]=WARN +[ 1.831099][ T1] Hardware name: BCM2711 +[ 1.831101][ T1] Call trace: +[ 1.831104][ T1] unwind_backtrace from show_stack+0x18/0x1c +[ 1.831120][ T1] show_stack from dump_stack_lvl+0x8c/0xcc +[ 1.831129][ T1] dump_stack_lvl from register_lock_class+0x9e8/0x9fc +[ 1.831141][ T1] register_lock_class from __lock_acquire+0x420/0x22c0 +[ 1.831154][ T1] __lock_acquire from lock_acquire+0x130/0x3f8 +[ 1.831166][ T1] lock_acquire from bcmgenet_get_stats64+0x4a4/0x4c8 +[ 1.831176][ T1] bcmgenet_get_stats64 from dev_get_stats+0x4c/0x408 +[ 1.831184][ T1] dev_get_stats from rtnl_fill_stats+0x38/0x120 +[ 1.831193][ T1] rtnl_fill_stats from rtnl_fill_ifinfo+0x7f8/0x1890 +[ 1.831203][ T1] rtnl_fill_ifinfo from rtmsg_ifinfo_build_skb+0xd0/0x138 +[ 1.831214][ T1] rtmsg_ifinfo_build_skb from rtmsg_ifinfo+0x48/0x8c +[ 1.831225][ T1] rtmsg_ifinfo from register_netdevice+0x8c0/0x95c +[ 1.831237][ T1] register_netdevice from register_netdev+0x28/0x40 +[ 1.831247][ T1] register_netdev from bcmgenet_probe+0x690/0x6bc +[ 1.831255][ T1] bcmgenet_probe from platform_probe+0x64/0xbc +[ 1.831263][ T1] platform_probe from really_probe+0xd0/0x2d4 +[ 1.831269][ T1] really_probe from __driver_probe_device+0x90/0x1a4 +[ 1.831273][ T1] __driver_probe_device from driver_probe_device+0x38/0x11c +[ 1.831278][ T1] driver_probe_device from __driver_attach+0x9c/0x18c +[ 1.831282][ T1] __driver_attach from bus_for_each_dev+0x84/0xd4 +[ 1.831291][ T1] bus_for_each_dev from bus_add_driver+0xd4/0x1f4 +[ 1.831303][ T1] bus_add_driver from driver_register+0x88/0x120 +[ 1.831312][ T1] driver_register from do_one_initcall+0x78/0x360 +[ 1.831320][ T1] do_one_initcall from kernel_init_freeable+0x2bc/0x314 +[ 1.831331][ T1] kernel_init_freeable from kernel_init+0x1c/0x144 +[ 1.831339][ T1] kernel_init from ret_from_fork+0x14/0x20 +[ 1.831344][ T1] Exception stack(0xf082dfb0 to 0xf082dff8) +[ 1.831349][ T1] dfa0: 00000000 00000000 00000000 00000000 +[ 1.831353][ T1] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 1.831356][ T1] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 + +Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics") +Reviewed-by: Florian Fainelli +Signed-off-by: Ryo Takakura +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250702092417.46486-1-ryotkkr98@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 43fba7b47d1cd..64bc7b3afb514 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -4079,6 +4079,12 @@ static int bcmgenet_probe(struct platform_device *pdev) + for (i = 0; i <= priv->hw_params->rx_queues; i++) + priv->rx_rings[i].rx_max_coalesced_frames = 1; + ++ /* Initialize u64 stats seq counter for 32bit machines */ ++ for (i = 0; i <= priv->hw_params->rx_queues; i++) ++ u64_stats_init(&priv->rx_rings[i].stats64.syncp); ++ for (i = 0; i <= priv->hw_params->tx_queues; i++) ++ u64_stats_init(&priv->tx_rings[i].stats64.syncp); ++ + /* libphy will determine the link state */ + netif_carrier_off(dev); + +-- +2.53.0 + diff --git a/queue-6.1/net-bonding-update-the-slave-array-for-broadcast-mod.patch b/queue-6.1/net-bonding-update-the-slave-array-for-broadcast-mod.patch new file mode 100644 index 0000000000..42f88faaf0 --- /dev/null +++ b/queue-6.1/net-bonding-update-the-slave-array-for-broadcast-mod.patch @@ -0,0 +1,61 @@ +From 1e6d44e69033900ce8346238be2384eff7a283db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 20:51:36 +0800 +Subject: net: bonding: update the slave array for broadcast mode + +From: Tonghao Zhang + +[ Upstream commit e0caeb24f538c3c9c94f471882ceeb43d9dc2739 ] + +This patch fixes ce7a381697cb ("net: bonding: add broadcast_neighbor option for 802.3ad"). +Before this commit, on the broadcast mode, all devices were traversed using the +bond_for_each_slave_rcu. This patch supports traversing devices by using all_slaves. +Therefore, we need to update the slave array when enslave or release slave. + +Fixes: ce7a381697cb ("net: bonding: add broadcast_neighbor option for 802.3ad") +Cc: Simon Horman +Cc: Jonathan Corbet +Cc: Andrew Lunn +Cc: +Reported-by: Jiri Slaby +Tested-by: Jiri Slaby +Link: https://lore.kernel.org/all/a97e6e1e-81bc-4a79-8352-9e4794b0d2ca@kernel.org/ +Signed-off-by: Tonghao Zhang +Reviewed-by: Hangbin Liu +Reviewed-by: Nikolay Aleksandrov +Acked-by: Jay Vosburgh +Link: https://patch.msgid.link/20251016125136.16568-1-tonghao@bamaicloud.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index d3c41dc57e547..e9e2dec1dcb13 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -2258,7 +2258,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, + unblock_netpoll_tx(); + } + +- if (bond_mode_can_use_xmit_hash(bond)) ++ /* broadcast mode uses the all_slaves to loop through slaves. */ ++ if (bond_mode_can_use_xmit_hash(bond) || ++ BOND_MODE(bond) == BOND_MODE_BROADCAST) + bond_update_slave_arr(bond, NULL); + + if (!slave_dev->netdev_ops->ndo_bpf || +@@ -2432,7 +2434,8 @@ static int __bond_release_one(struct net_device *bond_dev, + + bond_upper_dev_unlink(bond, slave); + +- if (bond_mode_can_use_xmit_hash(bond)) ++ if (bond_mode_can_use_xmit_hash(bond) || ++ BOND_MODE(bond) == BOND_MODE_BROADCAST) + bond_update_slave_arr(bond, slave); + + slave_info(bond_dev, slave_dev, "Releasing %s interface\n", +-- +2.53.0 + diff --git a/queue-6.1/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-6.1/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..17a7710baa --- /dev/null +++ b/queue-6.1/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 00d1fe88aa027eda08300271c5c00d8c3b2ca912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index afa94f058f5f5..4ab296678b0b1 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -212,16 +212,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -369,7 +367,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -394,7 +392,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -493,7 +491,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -504,7 +502,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-6.1/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch b/queue-6.1/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch new file mode 100644 index 0000000000..6c06052546 --- /dev/null +++ b/queue-6.1/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch @@ -0,0 +1,58 @@ +From a312c10caca7237ac89c93433385aad3a5ef4179 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2026 03:18:36 -0700 +Subject: netconsole: avoid out-of-bounds access on empty string in + trim_newline() + +From: Breno Leitao + +[ Upstream commit 7079c8c13f2d33992bc846240517d88f4ab07781 ] + +trim_newline() unconditionally dereferences s[len - 1] after computing +len = strnlen(s, maxlen). When the string is empty, len is 0 and the +expression underflows to s[(size_t)-1], reading (and potentially +writing) one byte before the buffer. + +The two callers feed trim_newline() with the result of strscpy() from +configfs store callbacks (dev_name_store, userdatum_value_store). +configfs guarantees count >= 1 reaches the callback, but the byte +itself can be NUL: a userspace write(fd, "\0", 1) leaves the +destination empty after strscpy() and triggers the underflow. The OOB +write only fires if the adjacent byte happens to be '\n', so this is +not a security issue, but the access is undefined behaviour either way. + +This pattern is commonly flagged by LLM-based code reviewers. While it +is not a security fix, the underlying access is undefined behaviour and +the change is small and self-contained, so it is a reasonable candidate +for the stable trees. + +Guard the dereference on a non-zero length. + +Fixes: ae001dc67907 ("net: netconsole: move newline trimming to function") +Cc: stable@vger.kernel.org +Signed-off-by: Breno Leitao +Reviewed-by: Gustavo Luiz Duarte +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-netcons_trim_newline-v1-1-dc35889aeedf@debian.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/netconsole.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c +index d150287c01a7d..988a8a0a67003 100644 +--- a/drivers/net/netconsole.c ++++ b/drivers/net/netconsole.c +@@ -246,6 +246,8 @@ static void trim_newline(char *s, size_t maxlen) + size_t len; + + len = strnlen(s, maxlen); ++ if (!len) ++ return; + if (s[len - 1] == '\n') + s[len - 1] = '\0'; + } +-- +2.53.0 + diff --git a/queue-6.1/series b/queue-6.1/series index ba4759019f..2561818cbe 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -794,3 +794,15 @@ net-tls-fix-strparser-anchor-skb-leak-on-offload-rx-.patch net-sched-cls_flower-revert-unintended-changes.patch smb-client-correctly-handle-errorcontextdata-as-a-fl.patch smb-client-fix-oob-reads-parsing-symlink-error-respo.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +net-bcmgenet-initialize-u64-stats-seq-counter.patch +net-bcmgenet-fix-leaking-free_bds.patch +btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch +alsa-misc-use-guard-for-spin-locks.patch +alsa-core-serialize-deferred-fasync-state-checks.patch +asoc-sof-pcm-clear-the-susbstream-pointer-to-null-on.patch +asoc-sof-stream-ipc-check-for-cstream-nullity-in-sof.patch +mtd-spi-nor-spansion-enable-jffs2-write-buffer-for-s.patch +netconsole-avoid-out-of-bounds-access-on-empty-strin.patch +bonding-fix-null-pointer-dereference-in-actor_port_p.patch +net-bonding-update-the-slave-array-for-broadcast-mod.patch diff --git a/queue-6.12/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch b/queue-6.12/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch new file mode 100644 index 0000000000..3a40e479aa --- /dev/null +++ b/queue-6.12/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch @@ -0,0 +1,55 @@ +From 387c953cfa5407191c1f7bca3731d349f6284cdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2026 11:46:12 +0800 +Subject: erofs: fix offset truncation when shifting pgoff on 32-bit platforms + +From: Gao Xiang + +[ Upstream commit c99493ce409c3b98fec1616dbcf24c102e006deb ] + +On 32-bit platforms, pgoff_t is 32 bits wide, so left-shifting +large arbitrary pgoff_t values by PAGE_SHIFT performs 32-bit arithmetic +and silently truncates the result for pages beyond the 4 GiB boundary. + +Cast the page index to loff_t before shifting to produce a correct +64-bit byte offset. + +Fixes: 386292919c25 ("erofs: introduce readmore decompression strategy") +Fixes: 307210c262a2 ("erofs: verify metadata accesses for file-backed mounts") +Reviewed-by: Chao Yu +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/data.c | 2 +- + fs/erofs/zdata.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/erofs/data.c b/fs/erofs/data.c +index 192c7ed885acd..21476bd6ae9de 100644 +--- a/fs/erofs/data.c ++++ b/fs/erofs/data.c +@@ -39,7 +39,7 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, + * However, the data access range must be verified here in advance. + */ + if (buf->file) { +- fpos = index << PAGE_SHIFT; ++ fpos = (loff_t)index << PAGE_SHIFT; + err = rw_verify_area(READ, buf->file, &fpos, PAGE_SIZE); + if (err < 0) + return ERR_PTR(err); +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index a81b6e6aee59a..e438b8c9bf03b 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -1853,7 +1853,7 @@ static void z_erofs_pcluster_readmore(struct z_erofs_frontend *f, + + if (cur < PAGE_SIZE) + break; +- cur = (index << PAGE_SHIFT) - 1; ++ cur = ((loff_t)index << PAGE_SHIFT) - 1; + } + } + +-- +2.53.0 + diff --git a/queue-6.12/iommu-amd-put-list_add-del-dev_data-back-under-the-d.patch b/queue-6.12/iommu-amd-put-list_add-del-dev_data-back-under-the-d.patch new file mode 100644 index 0000000000..923f7a9d5b --- /dev/null +++ b/queue-6.12/iommu-amd-put-list_add-del-dev_data-back-under-the-d.patch @@ -0,0 +1,70 @@ +From 27d6c19efaee283e17698401e8157000375fd158 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2024 20:13:41 -0400 +Subject: iommu/amd: Put list_add/del(dev_data) back under the domain->lock + +From: Jason Gunthorpe + +[ Upstream commit 4a552f7890f0870f6d9fd4fbc6c05cea7bfd4503 ] + +The list domain->dev_list is protected by the domain->lock spinlock. +Any iteration, addition or removal must be under the lock. + +Move the list_del() up into the critical section. pdom_is_sva_capable(), +and destroy_gcr3_table() do not interact with the list element. + +Wrap the list_add() in a lock, it would make more sense if this was under +the same critical section as adjusting the refcounts earlier, but that +requires more complications. + +Fixes: d6b47dec3684 ("iommu/amd: Reduce domain lock scope in attach device path") +Signed-off-by: Jason Gunthorpe +Reviewed-by: Vasant Hegde +Link: https://lore.kernel.org/r/1-v1-3b9edcf8067d+3975-amd_dev_list_locking_jgg@nvidia.com +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd/iommu.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c +index 6f2ce142dff7a..65d61b9c7382c 100644 +--- a/drivers/iommu/amd/iommu.c ++++ b/drivers/iommu/amd/iommu.c +@@ -2292,6 +2292,7 @@ static int attach_device(struct device *dev, + struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); + struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data); + struct pci_dev *pdev; ++ unsigned long flags; + int ret = 0; + + mutex_lock(&dev_data->mutex); +@@ -2332,7 +2333,9 @@ static int attach_device(struct device *dev, + + /* Update data structures */ + dev_data->domain = domain; ++ spin_lock_irqsave(&domain->lock, flags); + list_add(&dev_data->list, &domain->dev_list); ++ spin_unlock_irqrestore(&domain->lock, flags); + + /* Update device table */ + dev_update_dte(dev_data, true); +@@ -2379,6 +2382,7 @@ static void detach_device(struct device *dev) + /* Flush IOTLB and wait for the flushes to finish */ + spin_lock_irqsave(&domain->lock, flags); + amd_iommu_domain_flush_all(domain); ++ list_del(&dev_data->list); + spin_unlock_irqrestore(&domain->lock, flags); + + /* Clear GCR3 table */ +@@ -2387,7 +2391,6 @@ static void detach_device(struct device *dev) + + /* Update data structures */ + dev_data->domain = NULL; +- list_del(&dev_data->list); + + /* decrease reference counters - needs to happen after the flushes */ + pdom_detach_iommu(iommu, domain); +-- +2.53.0 + diff --git a/queue-6.12/iommu-amd-reorder-attach-device-code.patch b/queue-6.12/iommu-amd-reorder-attach-device-code.patch new file mode 100644 index 0000000000..bf2b413c1b --- /dev/null +++ b/queue-6.12/iommu-amd-reorder-attach-device-code.patch @@ -0,0 +1,162 @@ +From 96bcce03db98c04e395057f9d71591ff32e792a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Oct 2024 06:35:54 +0000 +Subject: iommu/amd: Reorder attach device code + +From: Vasant Hegde + +[ Upstream commit 0b136493d3ffa1358783dcf5b9f866ceef2ff122 ] + +Ideally in attach device path, it should take dev_data lock before +making changes to device data including IOPF enablement. So far dev_data +was using spinlock and it was hitting lock order issue when it tries to +enable IOPF. Hence Commit 526606b0a199 ("iommu/amd: Fix Invalid wait +context issue") moved IOPF enablement outside dev_data->lock. + +Previous patch converted dev_data lock to mutex. Now its safe to call +amd_iommu_iopf_add_device() with dev_data->mutex. Hence move back PCI +device capability enablement (ATS, PRI, PASID) and IOPF enablement code +inside the lock. Also in attach_device(), update 'dev_data->domain' at +the end so that error handling becomes simple. + +Signed-off-by: Vasant Hegde +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20241030063556.6104-11-vasant.hegde@amd.com +Signed-off-by: Joerg Roedel +Stable-dep-of: 4a552f7890f0 ("iommu/amd: Put list_add/del(dev_data) back under the domain->lock") +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd/iommu.c | 65 +++++++++++++++++---------------------- + 1 file changed, 29 insertions(+), 36 deletions(-) + +diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c +index a5adc4714f5c9..6f2ce142dff7a 100644 +--- a/drivers/iommu/amd/iommu.c ++++ b/drivers/iommu/amd/iommu.c +@@ -2291,6 +2291,7 @@ static int attach_device(struct device *dev, + { + struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); + struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data); ++ struct pci_dev *pdev; + int ret = 0; + + mutex_lock(&dev_data->mutex); +@@ -2300,10 +2301,6 @@ static int attach_device(struct device *dev, + goto out; + } + +- /* Update data structures */ +- dev_data->domain = domain; +- list_add(&dev_data->list, &domain->dev_list); +- + /* Do reference counting */ + ret = pdom_attach_iommu(iommu, domain); + if (ret) +@@ -2318,6 +2315,28 @@ static int attach_device(struct device *dev, + } + } + ++ pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL; ++ if (pdev && pdom_is_sva_capable(domain)) { ++ pdev_enable_caps(pdev); ++ ++ /* ++ * Device can continue to function even if IOPF ++ * enablement failed. Hence in error path just ++ * disable device PRI support. ++ */ ++ if (amd_iommu_iopf_add_device(iommu, dev_data)) ++ pdev_disable_cap_pri(pdev); ++ } else if (pdev) { ++ pdev_enable_cap_ats(pdev); ++ } ++ ++ /* Update data structures */ ++ dev_data->domain = domain; ++ list_add(&dev_data->list, &domain->dev_list); ++ ++ /* Update device table */ ++ dev_update_dte(dev_data, true); ++ + out: + mutex_unlock(&dev_data->mutex); + +@@ -2332,7 +2351,6 @@ static void detach_device(struct device *dev) + struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); + struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data); + struct protection_domain *domain = dev_data->domain; +- bool ppr = dev_data->ppr; + unsigned long flags; + + mutex_lock(&dev_data->mutex); +@@ -2346,13 +2364,15 @@ static void detach_device(struct device *dev) + if (WARN_ON(!dev_data->domain)) + goto out; + +- if (ppr) { ++ /* Remove IOPF handler */ ++ if (dev_data->ppr) { + iopf_queue_flush_dev(dev); +- +- /* Updated here so that it gets reflected in DTE */ +- dev_data->ppr = false; ++ amd_iommu_iopf_remove_device(iommu, dev_data); + } + ++ if (dev_is_pci(dev)) ++ pdev_disable_caps(to_pci_dev(dev)); ++ + /* Clear DTE and flush the entry */ + dev_update_dte(dev_data, false); + +@@ -2374,14 +2394,6 @@ static void detach_device(struct device *dev) + + out: + mutex_unlock(&dev_data->mutex); +- +- /* Remove IOPF handler */ +- if (ppr) +- amd_iommu_iopf_remove_device(iommu, dev_data); +- +- if (dev_is_pci(dev)) +- pdev_disable_caps(to_pci_dev(dev)); +- + } + + static struct iommu_device *amd_iommu_probe_device(struct device *dev) +@@ -2670,7 +2682,6 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, + struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev); + struct protection_domain *domain = to_pdomain(dom); + struct amd_iommu *iommu = get_amd_iommu_from_dev(dev); +- struct pci_dev *pdev; + int ret; + + /* +@@ -2703,24 +2714,6 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, + } + #endif + +- pdev = dev_is_pci(dev_data->dev) ? to_pci_dev(dev_data->dev) : NULL; +- if (pdev && pdom_is_sva_capable(domain)) { +- pdev_enable_caps(pdev); +- +- /* +- * Device can continue to function even if IOPF +- * enablement failed. Hence in error path just +- * disable device PRI support. +- */ +- if (amd_iommu_iopf_add_device(iommu, dev_data)) +- pdev_disable_cap_pri(pdev); +- } else if (pdev) { +- pdev_enable_cap_ats(pdev); +- } +- +- /* Update device table */ +- dev_update_dte(dev_data, true); +- + return ret; + } + +-- +2.53.0 + diff --git a/queue-6.12/net-bcmgenet-fix-leaking-free_bds.patch b/queue-6.12/net-bcmgenet-fix-leaking-free_bds.patch new file mode 100644 index 0000000000..3c1754a748 --- /dev/null +++ b/queue-6.12/net-bcmgenet-fix-leaking-free_bds.patch @@ -0,0 +1,49 @@ +From 29406a37309ff3926cfae8bd4575ba048b2d65a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Apr 2026 10:57:55 -0700 +Subject: net: bcmgenet: fix leaking free_bds + +From: Justin Chen + +[ Upstream commit 3f3168300efb839028328d720ab3962f91d6a0d0 ] + +While reclaiming the tx queue we fast forward the write pointer to +drop any data in flight. These dropped frames are not added back +to the pool of free bds. We also need to tell the netdev that we +are dropping said data. + +Fixes: f1bacae8b655 ("net: bcmgenet: support reclaiming unsent Tx packets") +Signed-off-by: Justin Chen +Reviewed-by: Florian Fainelli +Reviewed-by: Nicolai Buchwitz +Tested-by: Nicolai Buchwitz +Link: https://patch.msgid.link/20260406175756.134567-3-justin.chen@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 1cad32ba101bb..1263d00058736 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1933,6 +1933,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + drop = (ring->prod_index - ring->c_index) & DMA_C_INDEX_MASK; + released += drop; + ring->prod_index = ring->c_index & DMA_C_INDEX_MASK; ++ ring->free_bds += drop; + while (drop--) { + cb_ptr = bcmgenet_put_txcb(priv, ring); + skb = cb_ptr->skb; +@@ -1944,6 +1945,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + } + if (skb) + dev_consume_skb_any(skb); ++ netdev_tx_reset_queue(netdev_get_tx_queue(dev, ring->index)); + bcmgenet_tdma_ring_writel(priv, ring->index, + ring->prod_index, TDMA_PROD_INDEX); + wr_ptr = ring->write_ptr * WORDS_PER_BD(priv); +-- +2.53.0 + diff --git a/queue-6.12/net-bcmgenet-initialize-u64-stats-seq-counter.patch b/queue-6.12/net-bcmgenet-initialize-u64-stats-seq-counter.patch new file mode 100644 index 0000000000..6ba87115b3 --- /dev/null +++ b/queue-6.12/net-bcmgenet-initialize-u64-stats-seq-counter.patch @@ -0,0 +1,82 @@ +From f65909a176cb9bc7a90196bd420311e5ec6d5ee0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Jul 2025 18:24:17 +0900 +Subject: net: bcmgenet: Initialize u64 stats seq counter + +From: Ryo Takakura + +[ Upstream commit ffc2c8c4a714df53a715827d6334ab9474424f6a ] + +Initialize u64 stats as it uses seq counter on 32bit machines +as suggested by lockdep below. + +[ 1.830953][ T1] INFO: trying to register non-static key. +[ 1.830993][ T1] The code is fine but needs lockdep annotation, or maybe +[ 1.831027][ T1] you didn't initialize this object before use? +[ 1.831057][ T1] turning off the locking correctness validator. +[ 1.831090][ T1] CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 6.16.0-rc2-v7l+ #1 PREEMPT +[ 1.831097][ T1] Tainted: [W]=WARN +[ 1.831099][ T1] Hardware name: BCM2711 +[ 1.831101][ T1] Call trace: +[ 1.831104][ T1] unwind_backtrace from show_stack+0x18/0x1c +[ 1.831120][ T1] show_stack from dump_stack_lvl+0x8c/0xcc +[ 1.831129][ T1] dump_stack_lvl from register_lock_class+0x9e8/0x9fc +[ 1.831141][ T1] register_lock_class from __lock_acquire+0x420/0x22c0 +[ 1.831154][ T1] __lock_acquire from lock_acquire+0x130/0x3f8 +[ 1.831166][ T1] lock_acquire from bcmgenet_get_stats64+0x4a4/0x4c8 +[ 1.831176][ T1] bcmgenet_get_stats64 from dev_get_stats+0x4c/0x408 +[ 1.831184][ T1] dev_get_stats from rtnl_fill_stats+0x38/0x120 +[ 1.831193][ T1] rtnl_fill_stats from rtnl_fill_ifinfo+0x7f8/0x1890 +[ 1.831203][ T1] rtnl_fill_ifinfo from rtmsg_ifinfo_build_skb+0xd0/0x138 +[ 1.831214][ T1] rtmsg_ifinfo_build_skb from rtmsg_ifinfo+0x48/0x8c +[ 1.831225][ T1] rtmsg_ifinfo from register_netdevice+0x8c0/0x95c +[ 1.831237][ T1] register_netdevice from register_netdev+0x28/0x40 +[ 1.831247][ T1] register_netdev from bcmgenet_probe+0x690/0x6bc +[ 1.831255][ T1] bcmgenet_probe from platform_probe+0x64/0xbc +[ 1.831263][ T1] platform_probe from really_probe+0xd0/0x2d4 +[ 1.831269][ T1] really_probe from __driver_probe_device+0x90/0x1a4 +[ 1.831273][ T1] __driver_probe_device from driver_probe_device+0x38/0x11c +[ 1.831278][ T1] driver_probe_device from __driver_attach+0x9c/0x18c +[ 1.831282][ T1] __driver_attach from bus_for_each_dev+0x84/0xd4 +[ 1.831291][ T1] bus_for_each_dev from bus_add_driver+0xd4/0x1f4 +[ 1.831303][ T1] bus_add_driver from driver_register+0x88/0x120 +[ 1.831312][ T1] driver_register from do_one_initcall+0x78/0x360 +[ 1.831320][ T1] do_one_initcall from kernel_init_freeable+0x2bc/0x314 +[ 1.831331][ T1] kernel_init_freeable from kernel_init+0x1c/0x144 +[ 1.831339][ T1] kernel_init from ret_from_fork+0x14/0x20 +[ 1.831344][ T1] Exception stack(0xf082dfb0 to 0xf082dff8) +[ 1.831349][ T1] dfa0: 00000000 00000000 00000000 00000000 +[ 1.831353][ T1] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 1.831356][ T1] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 + +Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics") +Reviewed-by: Florian Fainelli +Signed-off-by: Ryo Takakura +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250702092417.46486-1-ryotkkr98@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index f012025a517dd..1cad32ba101bb 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -4075,6 +4075,12 @@ static int bcmgenet_probe(struct platform_device *pdev) + for (i = 0; i <= priv->hw_params->rx_queues; i++) + priv->rx_rings[i].rx_max_coalesced_frames = 1; + ++ /* Initialize u64 stats seq counter for 32bit machines */ ++ for (i = 0; i <= priv->hw_params->rx_queues; i++) ++ u64_stats_init(&priv->rx_rings[i].stats64.syncp); ++ for (i = 0; i <= priv->hw_params->tx_queues; i++) ++ u64_stats_init(&priv->tx_rings[i].stats64.syncp); ++ + /* libphy will determine the link state */ + netif_carrier_off(dev); + +-- +2.53.0 + diff --git a/queue-6.12/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-6.12/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..1e67874902 --- /dev/null +++ b/queue-6.12/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 2f15bca95d5efc60a653b8f78e691f4f59d218bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index abb8cdb409c48..a7c8477810107 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -214,16 +214,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -371,7 +369,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -396,7 +394,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -496,7 +494,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -507,7 +505,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-6.12/netpoll-extract-ipv6-address-retrieval-function.patch b/queue-6.12/netpoll-extract-ipv6-address-retrieval-function.patch new file mode 100644 index 0000000000..0dcc25fc06 --- /dev/null +++ b/queue-6.12/netpoll-extract-ipv6-address-retrieval-function.patch @@ -0,0 +1,129 @@ +From a673d901b637e5979346f67d914b798ac0e712b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jun 2025 02:32:47 -0700 +Subject: netpoll: Extract IPv6 address retrieval function + +From: Breno Leitao + +[ Upstream commit 6ad7969a361cbec5822285fb39203678ff462b64 ] + +Extract the IPv6 address retrieval logic from netpoll_setup() into +a dedicated helper function netpoll_take_ipv6() to improve code +organization and readability. + +The function handles obtaining the local IPv6 address from the +network device, including proper address type matching between +local and remote addresses (link-local vs global), and includes +appropriate error handling when IPv6 is not supported or no +suitable address is available. + +Signed-off-by: Breno Leitao +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250618-netpoll_ip_ref-v1-3-c2ac00fe558f@debian.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 76b93a810757 ("netpoll: pass buffer size to egress_dev() to avoid MAC truncation") +Signed-off-by: Sasha Levin +--- + net/core/netpoll.c | 76 +++++++++++++++++++++++++++------------------- + 1 file changed, 44 insertions(+), 32 deletions(-) + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index b754341db50fe..59cb4d4d28e10 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -721,6 +721,47 @@ static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev, + } + } + ++/* ++ * Take the IPv6 from ndev and populate local_ip structure in netpoll ++ */ ++static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev) ++{ ++ char buf[MAC_ADDR_STR_LEN + 1]; ++ int err = -EDESTADDRREQ; ++ struct inet6_dev *idev; ++ ++ if (!IS_ENABLED(CONFIG_IPV6)) { ++ np_err(np, "IPv6 is not supported %s, aborting\n", ++ egress_dev(np, buf)); ++ return -EINVAL; ++ } ++ ++ idev = __in6_dev_get(ndev); ++ if (idev) { ++ struct inet6_ifaddr *ifp; ++ ++ read_lock_bh(&idev->lock); ++ list_for_each_entry(ifp, &idev->addr_list, if_list) { ++ if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) != ++ !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL)) ++ continue; ++ /* Got the IP, let's return */ ++ np->local_ip.in6 = ifp->addr; ++ err = 0; ++ break; ++ } ++ read_unlock_bh(&idev->lock); ++ } ++ if (err) { ++ np_err(np, "no IPv6 address for %s, aborting\n", ++ egress_dev(np, buf)); ++ return err; ++ } ++ ++ np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6); ++ return 0; ++} ++ + /* + * Take the IPv4 from ndev and populate local_ip structure in netpoll + */ +@@ -815,41 +856,12 @@ int netpoll_setup(struct netpoll *np) + err = netpoll_take_ipv4(np, ndev); + if (err) + goto put; +- ip_overwritten = true; + } else { +-#if IS_ENABLED(CONFIG_IPV6) +- struct inet6_dev *idev; +- +- err = -EDESTADDRREQ; +- idev = __in6_dev_get(ndev); +- if (idev) { +- struct inet6_ifaddr *ifp; +- +- read_lock_bh(&idev->lock); +- list_for_each_entry(ifp, &idev->addr_list, if_list) { +- if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) != +- !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL)) +- continue; +- np->local_ip.in6 = ifp->addr; +- ip_overwritten = true; +- err = 0; +- break; +- } +- read_unlock_bh(&idev->lock); +- } +- if (err) { +- np_err(np, "no IPv6 address for %s, aborting\n", +- egress_dev(np, buf)); ++ err = netpoll_take_ipv6(np, ndev); ++ if (err) + goto put; +- } else +- np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6); +-#else +- np_err(np, "IPv6 is not supported %s, aborting\n", +- egress_dev(np, buf)); +- err = -EINVAL; +- goto put; +-#endif + } ++ ip_overwritten = true; + } + + err = __netpoll_setup(np, ndev); +-- +2.53.0 + diff --git a/queue-6.12/netpoll-pass-buffer-size-to-egress_dev-to-avoid-mac-.patch b/queue-6.12/netpoll-pass-buffer-size-to-egress_dev-to-avoid-mac-.patch new file mode 100644 index 0000000000..1111c6689b --- /dev/null +++ b/queue-6.12/netpoll-pass-buffer-size-to-egress_dev-to-avoid-mac-.patch @@ -0,0 +1,134 @@ +From a8afa6649643ade6f4c3e7a9438ef8987890dc4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 02:58:41 -0700 +Subject: netpoll: pass buffer size to egress_dev() to avoid MAC truncation + +From: Breno Leitao + +[ Upstream commit 76b93a8107574006b25495664304ea9237494d70 ] + +egress_dev() formats np->dev_mac via snprintf() but receives buf as +a bare char *, so it cannot derive the buffer size from the pointer. The +size argument was hardcoded to MAC_ADDR_STR_LEN (3 * ETH_ALEN - 1 = 17), +which is silly wrong in two ways: + + 1) misleading kernel log output on the MAC-selected target path + (np->dev_name[0] == '\0'); for example "aa:bb:cc:dd:ee:ff doesn't + exist, aborting" was logged as "aa:bb:cc:dd:ee:f doesn't exist, + aborting". + + 2) the second argument of snprintf is the size of the buffer, not the + size of what you want to write. + +Add a bufsz parameter to egress_dev() and pass sizeof(buf) from each +caller, matching the standard snprintf() idiom and removing the +hardcoded size from the helper. + +Every caller already declares "char buf[MAC_ADDR_STR_LEN + 1]" so the +formatted MAC continues to fit. + +Tested by booting with + netconsole=6665@/aa:bb:cc:dd:ee:ff,6666@10.0.0.1/00:11:22:33:44:55 +on a kernel without a matching device. Pre-fix dmesg shows +"aa:bb:cc:dd:ee:f doesn't exist, aborting"; post-fix shows the full +"aa:bb:cc:dd:ee:ff doesn't exist, aborting". + +Fixes: f8a10bed32f5 ("netconsole: allow selection of egress interface via MAC address") +Cc: stable@vger.kernel.org +Signed-off-by: Breno Leitao +Link: https://patch.msgid.link/20260501-netpoll_snprintf_fix-v1-1-84b0566e6597@debian.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/netpoll.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/net/core/netpoll.c b/net/core/netpoll.c +index 59cb4d4d28e10..c48a47601c2f3 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -695,14 +695,16 @@ EXPORT_SYMBOL_GPL(__netpoll_setup); + /* + * Returns a pointer to a string representation of the identifier used + * to select the egress interface for the given netpoll instance. buf +- * must be a buffer of length at least MAC_ADDR_STR_LEN + 1. ++ * is used to format np->dev_mac when np->dev_name is empty; bufsz must ++ * be at least MAC_ADDR_STR_LEN + 1 to fit the formatted MAC address ++ * and its NUL terminator. + */ +-static char *egress_dev(struct netpoll *np, char *buf) ++static char *egress_dev(struct netpoll *np, char *buf, size_t bufsz) + { + if (np->dev_name[0]) + return np->dev_name; + +- snprintf(buf, MAC_ADDR_STR_LEN, "%pM", np->dev_mac); ++ snprintf(buf, bufsz, "%pM", np->dev_mac); + return buf; + } + +@@ -732,7 +734,7 @@ static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev) + + if (!IS_ENABLED(CONFIG_IPV6)) { + np_err(np, "IPv6 is not supported %s, aborting\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + return -EINVAL; + } + +@@ -754,7 +756,7 @@ static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev) + } + if (err) { + np_err(np, "no IPv6 address for %s, aborting\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + return err; + } + +@@ -774,14 +776,14 @@ static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev) + in_dev = __in_dev_get_rtnl(ndev); + if (!in_dev) { + np_err(np, "no IP address for %s, aborting\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + return -EDESTADDRREQ; + } + + ifa = rtnl_dereference(in_dev->ifa_list); + if (!ifa) { + np_err(np, "no IP address for %s, aborting\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + return -EDESTADDRREQ; + } + +@@ -823,7 +825,8 @@ int netpoll_setup(struct netpoll *np) + ndev = dev_getbyhwaddr(net, ARPHRD_ETHER, np->dev_mac); + + if (!ndev) { +- np_err(np, "%s doesn't exist, aborting\n", egress_dev(np, buf)); ++ np_err(np, "%s doesn't exist, aborting\n", ++ egress_dev(np, buf, sizeof(buf))); + err = -ENODEV; + goto unlock; + } +@@ -831,14 +834,14 @@ int netpoll_setup(struct netpoll *np) + + if (netdev_master_upper_dev_get(ndev)) { + np_err(np, "%s is a slave device, aborting\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + err = -EBUSY; + goto put; + } + + if (!netif_running(ndev)) { + np_info(np, "device %s not up yet, forcing it\n", +- egress_dev(np, buf)); ++ egress_dev(np, buf, sizeof(buf))); + + err = dev_open(ndev, NULL); + if (err) { +-- +2.53.0 + diff --git a/queue-6.12/page_pool-fix-incorrect-mp_ops-error-handling.patch b/queue-6.12/page_pool-fix-incorrect-mp_ops-error-handling.patch new file mode 100644 index 0000000000..f1a320914a --- /dev/null +++ b/queue-6.12/page_pool-fix-incorrect-mp_ops-error-handling.patch @@ -0,0 +1,46 @@ +From 0642645570af748c2c944b3be3852980f5cd03b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 03:03:46 +0000 +Subject: page_pool: fix incorrect mp_ops error handling + +From: Mina Almasry + +[ Upstream commit abadf0ff63be488dc502ecfc9f622929a21b7117 ] + +Minor fix to the memory provider error handling, we should be jumping to +free_ptr_ring in this error case rather than returning directly. + +Found by code-inspection. + +Cc: skhawaja@google.com + +Fixes: b400f4b87430 ("page_pool: Set `dma_sync` to false for devmem memory provider") +Signed-off-by: Mina Almasry +Reviewed-by: Samiullah Khawaja +Link: https://patch.msgid.link/20250821030349.705244-1-almasrymina@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/page_pool.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/core/page_pool.c b/net/core/page_pool.c +index 9c569a0371656..97ad4cc87be81 100644 +--- a/net/core/page_pool.c ++++ b/net/core/page_pool.c +@@ -285,8 +285,10 @@ static int page_pool_init(struct page_pool *pool, + } + + if (pool->mp_ops) { +- if (!pool->dma_map || !pool->dma_sync) +- return -EOPNOTSUPP; ++ if (!pool->dma_map || !pool->dma_sync) { ++ err = -EOPNOTSUPP; ++ goto free_ptr_ring; ++ } + + if (WARN_ON(!is_kernel_rodata((unsigned long)pool->mp_ops))) { + err = -EFAULT; +-- +2.53.0 + diff --git a/queue-6.12/perf-tool_pmu-fix-aggregation-on-duration_time.patch b/queue-6.12/perf-tool_pmu-fix-aggregation-on-duration_time.patch new file mode 100644 index 0000000000..f3f10f0246 --- /dev/null +++ b/queue-6.12/perf-tool_pmu-fix-aggregation-on-duration_time.patch @@ -0,0 +1,85 @@ +From c1de8148ea421f5250701310383fbcdcf6336390 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Apr 2025 22:03:58 -0700 +Subject: perf tool_pmu: Fix aggregation on duration_time + +From: Ian Rogers + +[ Upstream commit 68cb1567439fa325ba980f3b5b67f95d3953eafd ] + +evsel__count_has_error() fails counters when the enabled or running time +are 0. The duration_time event reads 0 when the cpu_map_idx != 0 to +avoid aggregating time over CPUs. Change the enable and running time +to always have a ratio of 100% so that evsel__count_has_error won't +fail. + +Before: +``` +$ sudo /tmp/perf/perf stat --per-core -a -M UNCORE_FREQ sleep 1 + + Performance counter stats for 'system wide': + +S0-D0-C0 1 2,615,819,485 UNC_CLOCK.SOCKET # 2.61 UNCORE_FREQ +S0-D0-C0 2 duration_time + + 1.002111784 seconds time elapsed +``` + +After: +``` +$ perf stat --per-core -a -M UNCORE_FREQ sleep 1 + + Performance counter stats for 'system wide': + +S0-D0-C0 1 758,160,296 UNC_CLOCK.SOCKET # 0.76 UNCORE_FREQ +S0-D0-C0 2 1,003,438,246 duration_time + + 1.002486017 seconds time elapsed +``` + +Note: the metric reads the value a different way and isn't impacted. + +Fixes: 240505b2d0adcdc8 ("perf tool_pmu: Factor tool events into their own PMU") +Reported-by: Stephane Eranian +Reviewed-by: James Clark +Signed-off-by: Ian Rogers +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Ian Rogers +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Thomas Richter +Link: https://lore.kernel.org/r/20250423050358.94310-1-irogers@google.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/tool_pmu.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c +index f41fed39d70d8..3d1d6b3352ec7 100644 +--- a/tools/perf/util/tool_pmu.c ++++ b/tools/perf/util/tool_pmu.c +@@ -392,8 +392,14 @@ int evsel__read_tool(struct evsel *evsel, int cpu_map_idx, int thread) + delta_start *= 1000000000 / ticks_per_sec; + } + count->val = delta_start; +- count->ena = count->run = delta_start; + count->lost = 0; ++ /* ++ * The values of enabled and running must make a ratio of 100%. The ++ * exact values don't matter as long as they are non-zero to avoid ++ * issues with evsel__count_has_error. ++ */ ++ count->ena++; ++ count->run++; + return 0; + } + +-- +2.53.0 + diff --git a/queue-6.12/series b/queue-6.12/series index 1ce51fc347..0de3fe902b 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -597,3 +597,13 @@ smb-client-fix-oob-reads-parsing-symlink-error-respo.patch loongarch-kvm-compile-switch.s-directly-into-the-ker.patch ntfs-d_compare-must-not-block.patch pci-initialize-temporary-device-in-new_id_store.patch +erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch +net-bcmgenet-initialize-u64-stats-seq-counter.patch +net-bcmgenet-fix-leaking-free_bds.patch +iommu-amd-reorder-attach-device-code.patch +iommu-amd-put-list_add-del-dev_data-back-under-the-d.patch +perf-tool_pmu-fix-aggregation-on-duration_time.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +netpoll-extract-ipv6-address-retrieval-function.patch +netpoll-pass-buffer-size-to-egress_dev-to-avoid-mac-.patch +page_pool-fix-incorrect-mp_ops-error-handling.patch diff --git a/queue-6.18/bpf-fix-sync_linked_regs-regarding-bpf_add_const32-z.patch b/queue-6.18/bpf-fix-sync_linked_regs-regarding-bpf_add_const32-z.patch new file mode 100644 index 0000000000..95b4ad3ab9 --- /dev/null +++ b/queue-6.18/bpf-fix-sync_linked_regs-regarding-bpf_add_const32-z.patch @@ -0,0 +1,138 @@ +From b8a2b373a51304530fe1038283aea7f9ffd4de7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2026 22:15:06 +0100 +Subject: bpf: Fix sync_linked_regs regarding BPF_ADD_CONST32 zext propagation + +From: Daniel Borkmann + +[ Upstream commit bc308be380c136800e1e94c6ce49cb53141d6506 ] + +Jenny reported that in sync_linked_regs() the BPF_ADD_CONST32 flag is +checked on known_reg (the register narrowed by a conditional branch) +instead of reg (the linked target register created by an alu32 operation). + +Example case with reg: + + 1. r6 = bpf_get_prandom_u32() + 2. r7 = r6 (linked, same id) + 3. w7 += 5 (alu32 -- r7 gets BPF_ADD_CONST32, zero-extended by CPU) + 4. if w6 < 0xFFFFFFFC goto safe (narrows r6 to [0xFFFFFFFC, 0xFFFFFFFF]) + 5. sync_linked_regs() propagates to r7 but does NOT call zext_32_to_64() + 6. Verifier thinks r7 is [0x100000001, 0x100000004] instead of [1, 4] + +Since known_reg above does not have BPF_ADD_CONST32 set above, zext_32_to_64() +is never called on alu32-derived linked registers. This causes the verifier +to track incorrect 64-bit bounds, while the CPU correctly zero-extends the +32-bit result. + +The code checking known_reg->id was correct however (see scalars_alu32_wrap +selftest case), but the real fix needs to handle both directions - zext +propagation should be done when either register has BPF_ADD_CONST32, since +the linked relationship involves a 32-bit operation regardless of which +side has the flag. + +Example case with known_reg (exercised also by scalars_alu32_wrap): + + 1. r1 = r0; w1 += 0x100 (alu32 -- r1 gets BPF_ADD_CONST32) + 2. if r1 > 0x80 - known_reg = r1 (has BPF_ADD_CONST32), reg = r0 (doesn't) + +Hence, fix it by checking for (reg->id | known_reg->id) & BPF_ADD_CONST32. + +Moreover, sync_linked_regs() also has a soundness issue when two linked +registers used different ALU widths: one with BPF_ADD_CONST32 and the +other with BPF_ADD_CONST64. The delta relationship between linked registers +assumes the same arithmetic width though. When one register went through +alu32 (CPU zero-extends the 32-bit result) and the other went through +alu64 (no zero-extension), the propagation produces incorrect bounds. + +Example: + + r6 = bpf_get_prandom_u32() // fully unknown + if r6 >= 0x100000000 goto out // constrain r6 to [0, U32_MAX] + r7 = r6 + w7 += 1 // alu32: r7.id = N | BPF_ADD_CONST32 + r8 = r6 + r8 += 2 // alu64: r8.id = N | BPF_ADD_CONST64 + if r7 < 0xFFFFFFFF goto out // narrows r7 to [0xFFFFFFFF, 0xFFFFFFFF] + +At the branch on r7, sync_linked_regs() runs with known_reg=r7 +(BPF_ADD_CONST32) and reg=r8 (BPF_ADD_CONST64). The delta path +computes: + + r8 = r7 + (delta_r8 - delta_r7) = 0xFFFFFFFF + (2 - 1) = 0x100000000 + +Then, because known_reg->id has BPF_ADD_CONST32, zext_32_to_64(r8) is +called, truncating r8 to [0, 0]. But r8 used a 64-bit ALU op -- the +CPU does NOT zero-extend it. The actual CPU value of r8 is +0xFFFFFFFE + 2 = 0x100000000, not 0. The verifier now underestimates +r8's 64-bit bounds, which is a soundness violation. + +Fix sync_linked_regs() by skipping propagation when the two registers +have mixed ALU widths (one BPF_ADD_CONST32, the other BPF_ADD_CONST64). + +Lastly, fix regsafe() used for path pruning: the existing checks used +"& BPF_ADD_CONST" to test for offset linkage, which treated +BPF_ADD_CONST32 and BPF_ADD_CONST64 as equivalent. + +Fixes: 7a433e519364 ("bpf: Support negative offsets, BPF_SUB, and alu32 for linked register tracking") +Reported-by: Jenny Guanni Qu +Co-developed-by: Puranjay Mohan +Signed-off-by: Puranjay Mohan +Signed-off-by: Daniel Borkmann +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20260319211507.213816-1-daniel@iogearbox.net +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index ebfa27d4002c5..3dcf591acd50d 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -16913,6 +16913,12 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s + continue; + if ((reg->id & ~BPF_ADD_CONST) != (known_reg->id & ~BPF_ADD_CONST)) + continue; ++ /* ++ * Skip mixed 32/64-bit links: the delta relationship doesn't ++ * hold across different ALU widths. ++ */ ++ if (((reg->id ^ known_reg->id) & BPF_ADD_CONST) == BPF_ADD_CONST) ++ continue; + if ((!(reg->id & BPF_ADD_CONST) && !(known_reg->id & BPF_ADD_CONST)) || + reg->off == known_reg->off) { + s32 saved_subreg_def = reg->subreg_def; +@@ -16940,7 +16946,7 @@ static void sync_linked_regs(struct bpf_verifier_state *vstate, struct bpf_reg_s + scalar32_min_max_add(reg, &fake_reg); + scalar_min_max_add(reg, &fake_reg); + reg->var_off = tnum_add(reg->var_off, fake_reg.var_off); +- if (known_reg->id & BPF_ADD_CONST32) ++ if ((reg->id | known_reg->id) & BPF_ADD_CONST32) + zext_32_to_64(reg); + reg_bounds_sync(reg); + } +@@ -19056,11 +19062,14 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, + * Also verify that new value satisfies old value range knowledge. + */ + +- /* ADD_CONST mismatch: different linking semantics */ +- if ((rold->id & BPF_ADD_CONST) && !(rcur->id & BPF_ADD_CONST)) +- return false; +- +- if (rold->id && !(rold->id & BPF_ADD_CONST) && (rcur->id & BPF_ADD_CONST)) ++ /* ++ * ADD_CONST flags must match exactly: BPF_ADD_CONST32 and ++ * BPF_ADD_CONST64 have different linking semantics in ++ * sync_linked_regs() (alu32 zero-extends, alu64 does not), ++ * so pruning across different flag types is unsafe. ++ */ ++ if (rold->id && ++ (rold->id & BPF_ADD_CONST) != (rcur->id & BPF_ADD_CONST)) + return false; + + /* Both have offset linkage: offsets must match */ +-- +2.53.0 + diff --git a/queue-6.18/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch b/queue-6.18/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch new file mode 100644 index 0000000000..b64dea7fee --- /dev/null +++ b/queue-6.18/erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch @@ -0,0 +1,55 @@ +From bde9bd5168c48a6040f3f57af74fc23dd917ee26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2026 11:46:12 +0800 +Subject: erofs: fix offset truncation when shifting pgoff on 32-bit platforms + +From: Gao Xiang + +[ Upstream commit c99493ce409c3b98fec1616dbcf24c102e006deb ] + +On 32-bit platforms, pgoff_t is 32 bits wide, so left-shifting +large arbitrary pgoff_t values by PAGE_SHIFT performs 32-bit arithmetic +and silently truncates the result for pages beyond the 4 GiB boundary. + +Cast the page index to loff_t before shifting to produce a correct +64-bit byte offset. + +Fixes: 386292919c25 ("erofs: introduce readmore decompression strategy") +Fixes: 307210c262a2 ("erofs: verify metadata accesses for file-backed mounts") +Reviewed-by: Chao Yu +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/data.c | 2 +- + fs/erofs/zdata.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/erofs/data.c b/fs/erofs/data.c +index 58aea2b48580c..d685ee1d9c554 100644 +--- a/fs/erofs/data.c ++++ b/fs/erofs/data.c +@@ -38,7 +38,7 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap) + * However, the data access range must be verified here in advance. + */ + if (buf->file) { +- fpos = index << PAGE_SHIFT; ++ fpos = (loff_t)index << PAGE_SHIFT; + err = rw_verify_area(READ, buf->file, &fpos, PAGE_SIZE); + if (err < 0) + return ERR_PTR(err); +diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c +index 71f01f0a07435..0f09f3ba32149 100644 +--- a/fs/erofs/zdata.c ++++ b/fs/erofs/zdata.c +@@ -1869,7 +1869,7 @@ static void z_erofs_pcluster_readmore(struct z_erofs_frontend *f, + + if (cur < PAGE_SIZE) + break; +- cur = (index << PAGE_SHIFT) - 1; ++ cur = ((loff_t)index << PAGE_SHIFT) - 1; + } + } + +-- +2.53.0 + diff --git a/queue-6.18/fuse-fix-race-when-disposing-stale-dentries.patch b/queue-6.18/fuse-fix-race-when-disposing-stale-dentries.patch new file mode 100644 index 0000000000..27bf3d3afb --- /dev/null +++ b/queue-6.18/fuse-fix-race-when-disposing-stale-dentries.patch @@ -0,0 +1,78 @@ +From 68854a07f0897fe16e57d0847472cb835719fac8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Jan 2026 15:53:38 +0100 +Subject: fuse: fix race when disposing stale dentries + +From: Miklos Szeredi + +[ Upstream commit cb8d2bdcb8241b66ca4ac4868f20e12cd6881ebc ] + +In fuse_dentry_tree_work() just before d_dispose_if_unused() the dentry +could get evicted, resulting in UAF. + +Move unlocking dentry_hash[i].lock to after the dispose. To do this, +fuse_dentry_tree_del_node() needs to be moved from fuse_dentry_prune() to +fuse_dentry_release() to prevent an ABBA deadlock. + +The lock ordering becomes: + + -> dentry_bucket.lock + -> dentry.d_lock + +Reported-by: Al Viro +Closes: https://lore.kernel.org/all/20251206014242.GO1712166@ZenIV/ +Fixes: ab84ad597386 ("fuse: new work queue to periodically invalidate expired dentries") +Signed-off-by: Miklos Szeredi +Link: https://patch.msgid.link/20260114145344.468856-2-mszeredi@redhat.com +Signed-off-by: Christian Brauner +Stable-dep-of: 1e2c1af1beb3 ("fuse: make sure dentry is evicted if stale") +Signed-off-by: Sasha Levin +--- + fs/fuse/dir.c | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index 98b174bd802f0..b7a6a5b6bbc8a 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -172,8 +172,8 @@ static void fuse_dentry_tree_work(struct work_struct *work) + if (time_after64(get_jiffies_64(), fd->time)) { + rb_erase(&fd->node, &dentry_hash[i].tree); + RB_CLEAR_NODE(&fd->node); +- spin_unlock(&dentry_hash[i].lock); + d_dispose_if_unused(fd->dentry, &dispose); ++ spin_unlock(&dentry_hash[i].lock); + cond_resched(); + spin_lock(&dentry_hash[i].lock); + } else +@@ -464,18 +464,12 @@ static int fuse_dentry_init(struct dentry *dentry) + return 0; + } + +-static void fuse_dentry_prune(struct dentry *dentry) ++static void fuse_dentry_release(struct dentry *dentry) + { + struct fuse_dentry *fd = dentry->d_fsdata; + + if (!RB_EMPTY_NODE(&fd->node)) + fuse_dentry_tree_del_node(dentry); +-} +- +-static void fuse_dentry_release(struct dentry *dentry) +-{ +- struct fuse_dentry *fd = dentry->d_fsdata; +- + kfree_rcu(fd, rcu); + } + +@@ -512,7 +506,6 @@ const struct dentry_operations fuse_dentry_operations = { + .d_revalidate = fuse_dentry_revalidate, + .d_delete = fuse_dentry_delete, + .d_init = fuse_dentry_init, +- .d_prune = fuse_dentry_prune, + .d_release = fuse_dentry_release, + .d_automount = fuse_dentry_automount, + }; +-- +2.53.0 + diff --git a/queue-6.18/fuse-make-sure-dentry-is-evicted-if-stale.patch b/queue-6.18/fuse-make-sure-dentry-is-evicted-if-stale.patch new file mode 100644 index 0000000000..9f7757d9fe --- /dev/null +++ b/queue-6.18/fuse-make-sure-dentry-is-evicted-if-stale.patch @@ -0,0 +1,44 @@ +From 40ee0619112f06285afaf85be5ea372030084484 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Jan 2026 15:53:39 +0100 +Subject: fuse: make sure dentry is evicted if stale + +From: Miklos Szeredi + +[ Upstream commit 1e2c1af1beb395841743e240a59ab37edc9a7d33 ] + +d_dispose_if_unused() may find the dentry with a positive refcount, in +which case it won't be put on the dispose list even though it has already +timed out. + +"Reinstall" the d_delete() callback, which was optimized out in +fuse_dentry_settime(). This will result in the dentry being evicted as +soon as the refcount hits zero. + +Fixes: ab84ad597386 ("fuse: new work queue to periodically invalidate expired dentries") +Signed-off-by: Miklos Szeredi +Link: https://patch.msgid.link/20260114145344.468856-3-mszeredi@redhat.com +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/fuse/dir.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index b7a6a5b6bbc8a..ac5d0c305b51f 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -172,6 +172,10 @@ static void fuse_dentry_tree_work(struct work_struct *work) + if (time_after64(get_jiffies_64(), fd->time)) { + rb_erase(&fd->node, &dentry_hash[i].tree); + RB_CLEAR_NODE(&fd->node); ++ spin_lock(&fd->dentry->d_lock); ++ /* If dentry is still referenced, let next dput release it */ ++ fd->dentry->d_flags |= DCACHE_OP_DELETE; ++ spin_unlock(&fd->dentry->d_lock); + d_dispose_if_unused(fd->dentry, &dispose); + spin_unlock(&dentry_hash[i].lock); + cond_resched(); +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-fix-a-copy-and-paste-bug-in-probe.patch b/queue-6.18/net-airoha-fix-a-copy-and-paste-bug-in-probe.patch new file mode 100644 index 0000000000..b626a870f8 --- /dev/null +++ b/queue-6.18/net-airoha-fix-a-copy-and-paste-bug-in-probe.patch @@ -0,0 +1,47 @@ +From 2884c41f4c4365bdc7dd9e763db0bdbbc13f8e0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 14:23:35 +0300 +Subject: net: airoha: Fix a copy and paste bug in probe() + +From: Dan Carpenter + +[ Upstream commit 05e090620bacf317020f9591cfff8926093380bd ] + +This code has a copy and paste bug where it accidentally checks "if (err)" +instead of checking if "xsi_rsts" is NULL. Also, as a free bonus, I +changed the allocation from kzalloc() to kcalloc() which is a kernel +hardening measure to protect against integer overflows. + +Fixes: 5863b4e065e2 ("net: airoha: Add airoha_eth_soc_data struct") +Signed-off-by: Dan Carpenter +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/aPtht6y5DRokn9zv@stanley.mountain +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index 81ecfc1a1094c..4364f4320428a 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -3097,11 +3097,11 @@ static int airoha_probe(struct platform_device *pdev) + return err; + } + +- xsi_rsts = devm_kzalloc(eth->dev, +- eth->soc->num_xsi_rsts * sizeof(*xsi_rsts), ++ xsi_rsts = devm_kcalloc(eth->dev, ++ eth->soc->num_xsi_rsts, sizeof(*xsi_rsts), + GFP_KERNEL); +- if (err) +- return err; ++ if (!xsi_rsts) ++ return -ENOMEM; + + eth->xsi_rsts = xsi_rsts; + for (i = 0; i < eth->soc->num_xsi_rsts; i++) +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-fix-vip-configuration-for-an7583-soc.patch b/queue-6.18/net-airoha-fix-vip-configuration-for-an7583-soc.patch new file mode 100644 index 0000000000..af5a1eb660 --- /dev/null +++ b/queue-6.18/net-airoha-fix-vip-configuration-for-an7583-soc.patch @@ -0,0 +1,176 @@ +From 5de3250c7a412ddd931d3499a078965fa780df03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Apr 2026 09:57:29 +0200 +Subject: net: airoha: Fix VIP configuration for AN7583 SoC + +From: Lorenzo Bianconi + +[ Upstream commit 1acdfbdb516b32165a8ecd1d5f8c68e4eac64637 ] + +EN7581 and AN7583 SoCs have different VIP definitions. Introduce +get_vip_port callback in airoha_eth_soc_data struct in order to take +into account EN7581 and AN7583 VIP register layout and definition +differences. +Introduce nbq parameter in airoha_gdm_port struct. At the moment nbq +is set statically to value previously used in airhoha_set_gdm2_loopback +routine and it will be read from device tree in subsequent patches. + +Fixes: e4e5ce823bdd ("net: airoha: Add AN7583 SoC support") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260412-airoha-7583-vip-fix-v1-1-c35e02b054bb@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 66 ++++++++++++++++++------ + drivers/net/ethernet/airoha/airoha_eth.h | 2 + + 2 files changed, 51 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index c5f509cd52e63..27d62acfcc39c 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -107,19 +107,7 @@ static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, + struct airoha_eth *eth = port->qdma->eth; + u32 vip_port; + +- switch (port->id) { +- case AIROHA_GDM3_IDX: +- /* FIXME: handle XSI_PCIE1_PORT */ +- vip_port = XSI_PCIE0_VIP_PORT_MASK; +- break; +- case AIROHA_GDM4_IDX: +- /* FIXME: handle XSI_USB_PORT */ +- vip_port = XSI_ETH_VIP_PORT_MASK; +- break; +- default: +- return 0; +- } +- ++ vip_port = eth->soc->ops.get_vip_port(port, port->nbq); + if (enable) { + airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port); + airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port); +@@ -1809,7 +1797,7 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p) + static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + { + struct airoha_eth *eth = port->qdma->eth; +- u32 val, pse_port, chan, nbq; ++ u32 val, pse_port, chan; + int src_port; + + /* Forward the traffic to the proper GDM port */ +@@ -1839,9 +1827,7 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); + airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); + +- /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ +- nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; +- src_port = eth->soc->ops.get_src_port_id(port, nbq); ++ src_port = eth->soc->ops.get_src_port_id(port, port->nbq); + if (src_port < 0) + return src_port; + +@@ -3034,6 +3020,8 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, + port->qdma = qdma; + port->dev = dev; + port->id = id; ++ /* XXX: Read nbq from DTS */ ++ port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; + eth->ports[p] = port; + + return airoha_metadata_dst_alloc(port); +@@ -3229,6 +3217,28 @@ static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) + return -EINVAL; + } + ++static u32 airoha_en7581_get_vip_port(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case AIROHA_GDM3_IDX: ++ if (nbq == 4) ++ return XSI_PCIE0_VIP_PORT_MASK; ++ if (nbq == 5) ++ return XSI_PCIE1_VIP_PORT_MASK; ++ break; ++ case AIROHA_GDM4_IDX: ++ if (!nbq) ++ return XSI_ETH_VIP_PORT_MASK; ++ if (nbq == 1) ++ return XSI_USB_VIP_PORT_MASK; ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ + static const char * const an7583_xsi_rsts_names[] = { + "xsi-mac", + "hsi0-mac", +@@ -3258,6 +3268,26 @@ static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) + return -EINVAL; + } + ++static u32 airoha_an7583_get_vip_port(struct airoha_gdm_port *port, int nbq) ++{ ++ switch (port->id) { ++ case AIROHA_GDM3_IDX: ++ if (!nbq) ++ return XSI_ETH_VIP_PORT_MASK; ++ break; ++ case AIROHA_GDM4_IDX: ++ if (!nbq) ++ return XSI_PCIE0_VIP_PORT_MASK; ++ if (nbq == 1) ++ return XSI_USB_VIP_PORT_MASK; ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ + static const struct airoha_eth_soc_data en7581_soc_data = { + .version = 0x7581, + .xsi_rsts_names = en7581_xsi_rsts_names, +@@ -3265,6 +3295,7 @@ static const struct airoha_eth_soc_data en7581_soc_data = { + .num_ppe = 2, + .ops = { + .get_src_port_id = airoha_en7581_get_src_port_id, ++ .get_vip_port = airoha_en7581_get_vip_port, + }, + }; + +@@ -3275,6 +3306,7 @@ static const struct airoha_eth_soc_data an7583_soc_data = { + .num_ppe = 1, + .ops = { + .get_src_port_id = airoha_an7583_get_src_port_id, ++ .get_vip_port = airoha_an7583_get_vip_port, + }, + }; + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h +index 33277cc577990..57e8ddb30a9c5 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.h ++++ b/drivers/net/ethernet/airoha/airoha_eth.h +@@ -536,6 +536,7 @@ struct airoha_gdm_port { + struct airoha_qdma *qdma; + struct net_device *dev; + int id; ++ int nbq; + + struct airoha_hw_stats stats; + +@@ -576,6 +577,7 @@ struct airoha_eth_soc_data { + int num_ppe; + struct { + int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); ++ u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq); + } ops; + }; + +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-move-entries-to-queue-head-in-case-of-dma.patch b/queue-6.18/net-airoha-move-entries-to-queue-head-in-case-of-dma.patch new file mode 100644 index 0000000000..3ed964b1cc --- /dev/null +++ b/queue-6.18/net-airoha-move-entries-to-queue-head-in-case-of-dma.patch @@ -0,0 +1,48 @@ +From 410c3ca0b7cd5fcb1a22b4bd0415eb995818a95c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Apr 2026 14:02:31 +0200 +Subject: net: airoha: Move entries to queue head in case of DMA mapping + failure in airoha_dev_xmit() + +From: Lorenzo Bianconi + +[ Upstream commit 75df490c9e8457990c8b227650f6491218ce018b ] + +In order to respect the original descriptor order and avoid any +potential IOMMU fault or memory corruption, move pending queue entries +to the head of hw queue tx_list if the DMA mapping of current inflight +packet fails in airoha_dev_xmit routine. + +Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260429-airoha-xmit-unmap-error-path-v2-1-32e43b7c6d25@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index 4364f4320428a..b4dfab2702cb9 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -2136,14 +2136,12 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, + return NETDEV_TX_OK; + + error_unmap: +- while (!list_empty(&tx_list)) { +- e = list_first_entry(&tx_list, struct airoha_queue_entry, +- list); ++ list_for_each_entry(e, &tx_list, list) { + dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len, + DMA_TO_DEVICE); + e->dma_addr = 0; +- list_move_tail(&e->list, &q->tx_list); + } ++ list_splice(&tx_list, &q->tx_list); + + spin_unlock_bh(&q->lock); + error: +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-move-ndesc-initialization-at-end-of-airoh.patch-22905 b/queue-6.18/net-airoha-move-ndesc-initialization-at-end-of-airoh.patch-22905 new file mode 100644 index 0000000000..2c647f8af7 --- /dev/null +++ b/queue-6.18/net-airoha-move-ndesc-initialization-at-end-of-airoh.patch-22905 @@ -0,0 +1,65 @@ +From 54120efa72ccff9fdeb4bf1a37c61e92d19ca436 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Apr 2026 08:36:31 +0200 +Subject: net: airoha: Move ndesc initialization at end of + airoha_qdma_init_tx() + +From: Lorenzo Bianconi + +[ Upstream commit f329924bb49458c65297f1361f545816a5b90998 ] + +If queue entry list allocation fails in airoha_qdma_init_tx_queue routine, +airoha_qdma_cleanup_tx_queue() will trigger a NULL pointer dereference +accessing the queue entry array. The issue is due to the early ndesc +initialization in airoha_qdma_init_tx_queue(). Fix the issue moving ndesc +initialization at end of airoha_qdma_init_tx routine. + +Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-1-e04bcc2c9642@kernel.org +Reviewed-by: Simon Horman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index b4dfab2702cb9..3f97a0135f7f8 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -1019,27 +1019,27 @@ static int airoha_qdma_init_tx_queue(struct airoha_queue *q, + dma_addr_t dma_addr; + + spin_lock_init(&q->lock); +- q->ndesc = size; + q->qdma = qdma; + q->free_thr = 1 + MAX_SKB_FRAGS; + INIT_LIST_HEAD(&q->tx_list); + +- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry), ++ q->entry = devm_kzalloc(eth->dev, size * sizeof(*q->entry), + GFP_KERNEL); + if (!q->entry) + return -ENOMEM; + +- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc), ++ q->desc = dmam_alloc_coherent(eth->dev, size * sizeof(*q->desc), + &dma_addr, GFP_KERNEL); + if (!q->desc) + return -ENOMEM; + +- for (i = 0; i < q->ndesc; i++) { ++ for (i = 0; i < size; i++) { + u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1); + + list_add_tail(&q->entry[i].list, &q->tx_list); + WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val)); + } ++ q->ndesc = size; + + /* xmit ring drop default setting */ + airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid), +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-remove-code-duplication-in-airoha_regs.h.patch b/queue-6.18/net-airoha-remove-code-duplication-in-airoha_regs.h.patch new file mode 100644 index 0000000000..e312c7fa11 --- /dev/null +++ b/queue-6.18/net-airoha-remove-code-duplication-in-airoha_regs.h.patch @@ -0,0 +1,355 @@ +From 5c3d814cd4f78ee791504cb4f5b18267cc2397ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 09:11:12 +0200 +Subject: net: airoha: Remove code duplication in airoha_regs.h + +From: Lorenzo Bianconi + +[ Upstream commit 99ad2b6815f41acbec15ab051ccc79b11b05710a ] + +This patch does not introduce any logical change, it just removes +duplicated code in airoha_regs.h. +Fix naming conventions in airoha_regs.h. + +Reviewed-by: Simon Horman +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251022-airoha-regs-cosmetics-v2-1-e0425b3f2c2c@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1acdfbdb516b ("net: airoha: Fix VIP configuration for AN7583 SoC") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 102 ++++++++++---------- + drivers/net/ethernet/airoha/airoha_regs.h | 109 ++++++++++------------ + 2 files changed, 100 insertions(+), 111 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index 3f97a0135f7f8..269ed7179e6c9 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -137,11 +137,11 @@ static void airoha_fe_maccr_init(struct airoha_eth *eth) + + for (p = 1; p <= ARRAY_SIZE(eth->ports); p++) + airoha_fe_set(eth, REG_GDM_FWD_CFG(p), +- GDM_TCP_CKSUM | GDM_UDP_CKSUM | GDM_IP4_CKSUM | +- GDM_DROP_CRC_ERR); ++ GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK | ++ GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK); + +- airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK, +- FIELD_PREP(CDM1_VLAN_MASK, 0x8100)); ++ airoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK, ++ FIELD_PREP(CDM_VLAN_MASK, 0x8100)); + + airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD); + } +@@ -405,46 +405,46 @@ static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth) + static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth) + { + /* CDM1_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_22 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_22), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_08 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_08), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_21 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_21), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_24 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_24), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), + CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM1_CRSN_QSEL(CRSN_25 >> 2), +- CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM1_CRSN_QSEL_REASON_MASK(CRSN_25), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), + CDM_CRSN_QSEL_Q1)); + /* CDM2_CRSN_QSEL */ +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_08 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_08), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_08), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_08), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_21 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_21), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_21), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_21), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_22 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_22), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_22), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_22), + CDM_CRSN_QSEL_Q1)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_24 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_24), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_24), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_24), + CDM_CRSN_QSEL_Q6)); +- airoha_fe_rmw(eth, REG_CDM2_CRSN_QSEL(CRSN_25 >> 2), +- CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), +- FIELD_PREP(CDM2_CRSN_QSEL_REASON_MASK(CRSN_25), ++ airoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 >> 2), ++ CDM_CRSN_QSEL_REASON_MASK(CRSN_25), ++ FIELD_PREP(CDM_CRSN_QSEL_REASON_MASK(CRSN_25), + CDM_CRSN_QSEL_Q1)); + } + +@@ -464,18 +464,18 @@ static int airoha_fe_init(struct airoha_eth *eth) + airoha_fe_wr(eth, REG_FE_PCE_CFG, + PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK); + /* set vip queue selection to ring 1 */ +- airoha_fe_rmw(eth, REG_CDM1_FWD_CFG, CDM1_VIP_QSEL_MASK, +- FIELD_PREP(CDM1_VIP_QSEL_MASK, 0x4)); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_VIP_QSEL_MASK, +- FIELD_PREP(CDM2_VIP_QSEL_MASK, 0x4)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK, ++ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK, ++ FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4)); + /* set GDM4 source interface offset to 8 */ +- airoha_fe_rmw(eth, REG_GDM4_SRC_PORT_SET, +- GDM4_SPORT_OFF2_MASK | +- GDM4_SPORT_OFF1_MASK | +- GDM4_SPORT_OFF0_MASK, +- FIELD_PREP(GDM4_SPORT_OFF2_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF1_MASK, 8) | +- FIELD_PREP(GDM4_SPORT_OFF0_MASK, 8)); ++ airoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4), ++ GDM_SPORT_OFF2_MASK | ++ GDM_SPORT_OFF1_MASK | ++ GDM_SPORT_OFF0_MASK, ++ FIELD_PREP(GDM_SPORT_OFF2_MASK, 8) | ++ FIELD_PREP(GDM_SPORT_OFF1_MASK, 8) | ++ FIELD_PREP(GDM_SPORT_OFF0_MASK, 8)); + + /* set PSE Page as 128B */ + airoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG, +@@ -501,8 +501,8 @@ static int airoha_fe_init(struct airoha_eth *eth) + airoha_fe_set(eth, REG_GDM_MISC_CFG, + GDM2_RDM_ACK_WAIT_PREF_MASK | + GDM2_CHN_VLD_MODE_MASK); +- airoha_fe_rmw(eth, REG_CDM2_FWD_CFG, CDM2_OAM_QSEL_MASK, +- FIELD_PREP(CDM2_OAM_QSEL_MASK, 15)); ++ airoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK, ++ FIELD_PREP(CDM_OAM_QSEL_MASK, 15)); + + /* init fragment and assemble Force Port */ + /* NPU Core-3, NPU Bridge Channel-3 */ +@@ -516,8 +516,8 @@ static int airoha_fe_init(struct airoha_eth *eth) + FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | + FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); + +- airoha_fe_set(eth, REG_GDM3_FWD_CFG, GDM3_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM4_FWD_CFG, GDM4_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); + + airoha_fe_crsn_qsel_init(eth); + +@@ -525,7 +525,7 @@ static int airoha_fe_init(struct airoha_eth *eth) + airoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK); + + /* default aging mode for mbi unlock issue */ +- airoha_fe_rmw(eth, REG_GDM2_CHN_RLS, ++ airoha_fe_rmw(eth, REG_GDM_CHN_RLS(2), + MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK, + FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) | + FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3)); +@@ -1816,7 +1816,7 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 + : FE_PSE_PORT_GDM4; + airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); +- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); ++ airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); + + /* Enable GDM2 loopback */ + airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); +diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h +index ebcce00d9bc6f..ed4e3407f4a0e 100644 +--- a/drivers/net/ethernet/airoha/airoha_regs.h ++++ b/drivers/net/ethernet/airoha/airoha_regs.h +@@ -23,6 +23,8 @@ + #define GDM3_BASE 0x1100 + #define GDM4_BASE 0x2500 + ++#define CDM_BASE(_n) \ ++ ((_n) == 2 ? CDM2_BASE : CDM1_BASE) + #define GDM_BASE(_n) \ + ((_n) == 4 ? GDM4_BASE : \ + (_n) == 3 ? GDM3_BASE : \ +@@ -109,30 +111,24 @@ + #define PATN_DP_MASK GENMASK(31, 16) + #define PATN_SP_MASK GENMASK(15, 0) + +-#define REG_CDM1_VLAN_CTRL CDM1_BASE +-#define CDM1_VLAN_MASK GENMASK(31, 16) ++#define REG_CDM_VLAN_CTRL(_n) CDM_BASE(_n) ++#define CDM_VLAN_MASK GENMASK(31, 16) + +-#define REG_CDM1_FWD_CFG (CDM1_BASE + 0x08) +-#define CDM1_VIP_QSEL_MASK GENMASK(24, 20) ++#define REG_CDM_FWD_CFG(_n) (CDM_BASE(_n) + 0x08) ++#define CDM_OAM_QSEL_MASK GENMASK(31, 27) ++#define CDM_VIP_QSEL_MASK GENMASK(24, 20) + +-#define REG_CDM1_CRSN_QSEL(_n) (CDM1_BASE + 0x10 + ((_n) << 2)) +-#define CDM1_CRSN_QSEL_REASON_MASK(_n) \ +- GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) +- +-#define REG_CDM2_FWD_CFG (CDM2_BASE + 0x08) +-#define CDM2_OAM_QSEL_MASK GENMASK(31, 27) +-#define CDM2_VIP_QSEL_MASK GENMASK(24, 20) +- +-#define REG_CDM2_CRSN_QSEL(_n) (CDM2_BASE + 0x10 + ((_n) << 2)) +-#define CDM2_CRSN_QSEL_REASON_MASK(_n) \ ++#define REG_CDM_CRSN_QSEL(_n, _m) (CDM_BASE(_n) + 0x10 + ((_m) << 2)) ++#define CDM_CRSN_QSEL_REASON_MASK(_n) \ + GENMASK(4 + (((_n) % 4) << 3), (((_n) % 4) << 3)) + + #define REG_GDM_FWD_CFG(_n) GDM_BASE(_n) +-#define GDM_DROP_CRC_ERR BIT(23) +-#define GDM_IP4_CKSUM BIT(22) +-#define GDM_TCP_CKSUM BIT(21) +-#define GDM_UDP_CKSUM BIT(20) +-#define GDM_STRIP_CRC BIT(16) ++#define GDM_PAD_EN_MASK BIT(28) ++#define GDM_DROP_CRC_ERR_MASK BIT(23) ++#define GDM_IP4_CKSUM_MASK BIT(22) ++#define GDM_TCP_CKSUM_MASK BIT(21) ++#define GDM_UDP_CKSUM_MASK BIT(20) ++#define GDM_STRIP_CRC_MASK BIT(16) + #define GDM_UCFQ_MASK GENMASK(15, 12) + #define GDM_BCFQ_MASK GENMASK(11, 8) + #define GDM_MCFQ_MASK GENMASK(7, 4) +@@ -156,6 +152,10 @@ + #define LBK_CHAN_MODE_MASK BIT(1) + #define LPBK_EN_MASK BIT(0) + ++#define REG_GDM_CHN_RLS(_n) (GDM_BASE(_n) + 0x20) ++#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) ++#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) ++ + #define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24) + #define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28) + +@@ -168,10 +168,10 @@ + #define FE_GDM_MIB_RX_CLEAR_MASK BIT(1) + #define FE_GDM_MIB_TX_CLEAR_MASK BIT(0) + +-#define REG_FE_GDM1_MIB_CFG (GDM1_BASE + 0xf4) ++#define REG_FE_GDM_MIB_CFG(_n) (GDM_BASE(_n) + 0xf4) + #define FE_STRICT_RFC2819_MODE_MASK BIT(31) +-#define FE_GDM1_TX_MIB_SPLIT_EN_MASK BIT(17) +-#define FE_GDM1_RX_MIB_SPLIT_EN_MASK BIT(16) ++#define FE_GDM_TX_MIB_SPLIT_EN_MASK BIT(17) ++#define FE_GDM_RX_MIB_SPLIT_EN_MASK BIT(16) + #define FE_TX_MIB_ID_MASK GENMASK(15, 8) + #define FE_RX_MIB_ID_MASK GENMASK(7, 0) + +@@ -214,6 +214,33 @@ + #define REG_FE_GDM_RX_ETH_L511_CNT_L(_n) (GDM_BASE(_n) + 0x198) + #define REG_FE_GDM_RX_ETH_L1023_CNT_L(_n) (GDM_BASE(_n) + 0x19c) + ++#define REG_GDM_SRC_PORT_SET(_n) (GDM_BASE(_n) + 0x23c) ++#define GDM_SPORT_OFF2_MASK GENMASK(19, 16) ++#define GDM_SPORT_OFF1_MASK GENMASK(15, 12) ++#define GDM_SPORT_OFF0_MASK GENMASK(11, 8) ++ ++#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) ++#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) ++#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) ++#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) ++ ++#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) ++#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) ++#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) ++#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) ++#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) ++#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) ++#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) ++#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) ++#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) ++#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) ++#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) ++#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) ++#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) ++#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) ++#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) ++#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) ++ + #define REG_PPE_GLO_CFG(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x200) + #define PPE_GLO_CFG_BUSY_MASK BIT(31) + #define PPE_GLO_CFG_FLOW_DROP_UPDATE_MASK BIT(9) +@@ -326,44 +353,6 @@ + + #define REG_UPDMEM_DATA(_n) (((_n) ? PPE2_BASE : PPE1_BASE) + 0x374) + +-#define REG_FE_GDM_TX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x280) +-#define REG_FE_GDM_TX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x284) +-#define REG_FE_GDM_TX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x288) +-#define REG_FE_GDM_TX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x28c) +- +-#define REG_FE_GDM_RX_OK_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x290) +-#define REG_FE_GDM_RX_OK_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x294) +-#define REG_FE_GDM_RX_ETH_PKT_CNT_H(_n) (GDM_BASE(_n) + 0x298) +-#define REG_FE_GDM_RX_ETH_BYTE_CNT_H(_n) (GDM_BASE(_n) + 0x29c) +-#define REG_FE_GDM_TX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2b8) +-#define REG_FE_GDM_TX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2bc) +-#define REG_FE_GDM_TX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2c0) +-#define REG_FE_GDM_TX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2c4) +-#define REG_FE_GDM_TX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2c8) +-#define REG_FE_GDM_TX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2cc) +-#define REG_FE_GDM_RX_ETH_E64_CNT_H(_n) (GDM_BASE(_n) + 0x2e8) +-#define REG_FE_GDM_RX_ETH_L64_CNT_H(_n) (GDM_BASE(_n) + 0x2ec) +-#define REG_FE_GDM_RX_ETH_L127_CNT_H(_n) (GDM_BASE(_n) + 0x2f0) +-#define REG_FE_GDM_RX_ETH_L255_CNT_H(_n) (GDM_BASE(_n) + 0x2f4) +-#define REG_FE_GDM_RX_ETH_L511_CNT_H(_n) (GDM_BASE(_n) + 0x2f8) +-#define REG_FE_GDM_RX_ETH_L1023_CNT_H(_n) (GDM_BASE(_n) + 0x2fc) +- +-#define REG_GDM2_CHN_RLS (GDM2_BASE + 0x20) +-#define MBI_RX_AGE_SEL_MASK GENMASK(26, 25) +-#define MBI_TX_AGE_SEL_MASK GENMASK(18, 17) +- +-#define REG_GDM3_FWD_CFG GDM3_BASE +-#define GDM3_PAD_EN_MASK BIT(28) +- +-#define REG_GDM4_FWD_CFG GDM4_BASE +-#define GDM4_PAD_EN_MASK BIT(28) +-#define GDM4_SPORT_OFFSET0_MASK GENMASK(11, 8) +- +-#define REG_GDM4_SRC_PORT_SET (GDM4_BASE + 0x23c) +-#define GDM4_SPORT_OFF2_MASK GENMASK(19, 16) +-#define GDM4_SPORT_OFF1_MASK GENMASK(15, 12) +-#define GDM4_SPORT_OFF0_MASK GENMASK(11, 8) +- + #define REG_IP_FRAG_FP 0x2010 + #define IP_ASSEMBLE_PORT_MASK GENMASK(24, 21) + #define IP_ASSEMBLE_NBQ_MASK GENMASK(20, 16) +-- +2.53.0 + diff --git a/queue-6.18/net-airoha-use-gdm-port-enum-value-whenever-possible.patch b/queue-6.18/net-airoha-use-gdm-port-enum-value-whenever-possible.patch new file mode 100644 index 0000000000..6a078cb607 --- /dev/null +++ b/queue-6.18/net-airoha-use-gdm-port-enum-value-whenever-possible.patch @@ -0,0 +1,143 @@ +From 39f9853a93ccf92b4a1da6118cbe6afd66c10641 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jan 2026 10:40:47 +0100 +Subject: net: airoha: Use gdm port enum value whenever possible + +From: Lorenzo Bianconi + +[ Upstream commit 4d513329b87c1bd0546d9f0288794e244322daa6 ] + +Use AIROHA_GDMx_IDX enum value whenever possible. +This patch is just cosmetic changes and does not introduce any logic one. + +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20260105-airoha-use-port-idx-enum-v1-1-503ca5763858@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1acdfbdb516b ("net: airoha: Fix VIP configuration for AN7583 SoC") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/airoha/airoha_eth.c | 40 +++++++++++++----------- + 1 file changed, 21 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c +index 269ed7179e6c9..c5f509cd52e63 100644 +--- a/drivers/net/ethernet/airoha/airoha_eth.c ++++ b/drivers/net/ethernet/airoha/airoha_eth.c +@@ -108,11 +108,11 @@ static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port, + u32 vip_port; + + switch (port->id) { +- case 3: ++ case AIROHA_GDM3_IDX: + /* FIXME: handle XSI_PCIE1_PORT */ + vip_port = XSI_PCIE0_VIP_PORT_MASK; + break; +- case 4: ++ case AIROHA_GDM4_IDX: + /* FIXME: handle XSI_USB_PORT */ + vip_port = XSI_ETH_VIP_PORT_MASK; + break; +@@ -516,8 +516,8 @@ static int airoha_fe_init(struct airoha_eth *eth) + FIELD_PREP(IP_ASSEMBLE_PORT_MASK, 0) | + FIELD_PREP(IP_ASSEMBLE_NBQ_MASK, 22)); + +- airoha_fe_set(eth, REG_GDM_FWD_CFG(3), GDM_PAD_EN_MASK); +- airoha_fe_set(eth, REG_GDM_FWD_CFG(4), GDM_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK); ++ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK); + + airoha_fe_crsn_qsel_init(eth); + +@@ -1815,27 +1815,29 @@ static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) + /* Forward the traffic to the proper GDM port */ + pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 + : FE_PSE_PORT_GDM4; +- airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); +- airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC_MASK); ++ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), ++ pse_port); ++ airoha_fe_clear(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX), ++ GDM_STRIP_CRC_MASK); + + /* Enable GDM2 loopback */ +- airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff); +- airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff); ++ airoha_fe_wr(eth, REG_GDM_TXCHN_EN(AIROHA_GDM2_IDX), 0xffffffff); ++ airoha_fe_wr(eth, REG_GDM_RXCHN_EN(AIROHA_GDM2_IDX), 0xffff); + + chan = port->id == AIROHA_GDM3_IDX ? airoha_is_7581(eth) ? 4 : 3 : 0; +- airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2), ++ airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX), + LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK, + FIELD_PREP(LPBK_CHAN_MASK, chan) | + LBK_GAP_MODE_MASK | LBK_LEN_MODE_MASK | + LBK_CHAN_MODE_MASK | LPBK_EN_MASK); +- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2), ++ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(AIROHA_GDM2_IDX), + GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK, + FIELD_PREP(GDM_SHORT_LEN_MASK, 60) | + FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU)); + + /* Disable VIP and IFC for GDM2 */ +- airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); +- airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); ++ airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX)); ++ airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX)); + + /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ + nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0; +@@ -1869,8 +1871,8 @@ static int airoha_dev_init(struct net_device *dev) + airoha_set_macaddr(port, dev->dev_addr); + + switch (port->id) { +- case 3: +- case 4: ++ case AIROHA_GDM3_IDX: ++ case AIROHA_GDM4_IDX: + /* If GDM2 is active we can't enable loopback */ + if (!eth->ports[1]) { + int err; +@@ -1880,7 +1882,7 @@ static int airoha_dev_init(struct net_device *dev) + return err; + } + fallthrough; +- case 2: ++ case AIROHA_GDM2_IDX: + if (airoha_ppe_is_enabled(eth, 1)) { + pse_port = FE_PSE_PORT_PPE2; + break; +@@ -3206,14 +3208,14 @@ static const char * const en7581_xsi_rsts_names[] = { + static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) + { + switch (port->id) { +- case 3: ++ case AIROHA_GDM3_IDX: + /* 7581 SoC supports PCIe serdes on GDM3 port */ + if (nbq == 4) + return HSGMII_LAN_7581_PCIE0_SRCPORT; + if (nbq == 5) + return HSGMII_LAN_7581_PCIE1_SRCPORT; + break; +- case 4: ++ case AIROHA_GDM4_IDX: + /* 7581 SoC supports eth and usb serdes on GDM4 port */ + if (!nbq) + return HSGMII_LAN_7581_ETH_SRCPORT; +@@ -3237,12 +3239,12 @@ static const char * const an7583_xsi_rsts_names[] = { + static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq) + { + switch (port->id) { +- case 3: ++ case AIROHA_GDM3_IDX: + /* 7583 SoC supports eth serdes on GDM3 port */ + if (!nbq) + return HSGMII_LAN_7583_ETH_SRCPORT; + break; +- case 4: ++ case AIROHA_GDM4_IDX: + /* 7583 SoC supports PCIe and USB serdes on GDM4 port */ + if (!nbq) + return HSGMII_LAN_7583_PCIE_SRCPORT; +-- +2.53.0 + diff --git a/queue-6.18/net-mana-fix-use-after-free-in-reset-service-rescan-.patch b/queue-6.18/net-mana-fix-use-after-free-in-reset-service-rescan-.patch new file mode 100644 index 0000000000..852993a918 --- /dev/null +++ b/queue-6.18/net-mana-fix-use-after-free-in-reset-service-rescan-.patch @@ -0,0 +1,75 @@ +From 66b8feb6db8c2e07a5acc237279785a9171c6cc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Dec 2025 05:10:54 -0800 +Subject: net: mana: Fix use-after-free in reset service rescan path + +From: Dipayaan Roy + +[ Upstream commit 3387a7ad478b46970ae8254049167d166e398aeb ] + +When mana_serv_reset() encounters -ETIMEDOUT or -EPROTO from +mana_gd_resume(), it performs a PCI rescan via mana_serv_rescan(). + +mana_serv_rescan() calls pci_stop_and_remove_bus_device(), which can +invoke the driver's remove path and free the gdma_context associated +with the device. After returning, mana_serv_reset() currently jumps to +the out label and attempts to clear gc->in_service, dereferencing a +freed gdma_context. + +The issue was observed with the following call logs: +[ 698.942636] BUG: unable to handle page fault for address: ff6c2b638088508d +[ 698.943121] #PF: supervisor write access in kernel mode +[ 698.943423] #PF: error_code(0x0002) - not-present page +[S[ 698.943793] Pat Dec 6 07:GD5 100000067 P4D 1002f7067 PUD 1002f8067 PMD 101bef067 PTE 0 +0:56 2025] hv_[n e 698.944283] Oops: Oops: 0002 [#1] SMP NOPTI +tvsc f8615163-00[ 698.944611] CPU: 28 UID: 0 PID: 249 Comm: kworker/28:1 +... +[Sat Dec 6 07:50:56 2025] R10: [ 699.121594] mana 7870:00:00.0 enP30832s1: Configured vPort 0 PD 18 DB 16 +000000000000001b R11: 0000000000000000 R12: ff44cf3f40270000 +[Sat Dec 6 07:50:56 2025] R13: 0000000000000001 R14: ff44cf3f402700c8 R15: ff44cf3f4021b405 +[Sat Dec 6 07:50:56 2025] FS: 0000000000000000(0000) GS:ff44cf7e9fcf9000(0000) knlGS:0000000000000000 +[Sat Dec 6 07:50:56 2025] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[Sat Dec 6 07:50:56 2025] CR2: ff6c2b638088508d CR3: 000000011fe43001 CR4: 0000000000b73ef0 +[Sat Dec 6 07:50:56 2025] Call Trace: +[Sat Dec 6 07:50:56 2025] +[Sat Dec 6 07:50:56 2025] mana_serv_func+0x24/0x50 [mana] +[Sat Dec 6 07:50:56 2025] process_one_work+0x190/0x350 +[Sat Dec 6 07:50:56 2025] worker_thread+0x2b7/0x3d0 +[Sat Dec 6 07:50:56 2025] kthread+0xf3/0x200 +[Sat Dec 6 07:50:56 2025] ? __pfx_worker_thread+0x10/0x10 +[Sat Dec 6 07:50:56 2025] ? __pfx_kthread+0x10/0x10 +[Sat Dec 6 07:50:56 2025] ret_from_fork+0x21a/0x250 +[Sat Dec 6 07:50:56 2025] ? __pfx_kthread+0x10/0x10 +[Sat Dec 6 07:50:56 2025] ret_from_fork_asm+0x1a/0x30 +[Sat Dec 6 07:50:56 2025] + +Fix this by returning immediately after mana_serv_rescan() to avoid +accessing GC state that may no longer be valid. + +Fixes: 9bf66036d686 ("net: mana: Handle hardware recovery events when probing the device") +Reviewed-by: Simon Horman +Reviewed-by: Long Li +Signed-off-by: Dipayaan Roy +Link: https://patch.msgid.link/20251218131054.GA3173@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microsoft/mana/gdma_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c +index 0ad082b566f5e..45ee0774522a1 100644 +--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c ++++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c +@@ -481,7 +481,7 @@ static void mana_serv_reset(struct pci_dev *pdev) + /* Perform PCI rescan on device if we failed on HWC */ + dev_err(&pdev->dev, "MANA service: resume failed, rescanning\n"); + mana_serv_rescan(pdev); +- goto out; ++ return; + } + + if (ret) +-- +2.53.0 + diff --git a/queue-6.18/net-mana-init-gf_stats_work-before-potential-error-p.patch b/queue-6.18/net-mana-init-gf_stats_work-before-potential-error-p.patch new file mode 100644 index 0000000000..7a84867229 --- /dev/null +++ b/queue-6.18/net-mana-init-gf_stats_work-before-potential-error-p.patch @@ -0,0 +1,52 @@ +From 6d1d0e49a59db6318114a4cf019617081877d770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2026 05:47:36 -0700 +Subject: net: mana: Init gf_stats_work before potential error paths in probe + +From: Erni Sri Satya Vennela + +[ Upstream commit 6e8bc03349fe4f09567fa76235abf52bdaf83082 ] + +Move INIT_DELAYED_WORK(gf_stats_work) to before mana_create_eq(), +while keeping schedule_delayed_work() at its original location. + +Previously, if any function between mana_create_eq() and the +INIT_DELAYED_WORK call failed, mana_probe() would call mana_remove() +which unconditionally calls cancel_delayed_work_sync(gf_stats_work) +in __flush_work() or debug object warnings with +CONFIG_DEBUG_OBJECTS_WORK enabled. + +Fixes: be4f1d67ec56 ("net: mana: Add standard counter rx_missed_errors") +Signed-off-by: Erni Sri Satya Vennela +Link: https://patch.msgid.link/20260420124741.1056179-3-ernis@linux.microsoft.com +Reviewed-by: Simon Horman +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c +index 4b7e5acba7f76..d1eb77d540427 100644 +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -3607,6 +3607,8 @@ int mana_probe(struct gdma_dev *gd, bool resuming) + INIT_WORK(&ac->link_change_work, mana_link_state_handle); + } + ++ INIT_DELAYED_WORK(&ac->gf_stats_work, mana_gf_stats_work_handler); ++ + err = mana_create_eq(ac); + if (err) { + dev_err(dev, "Failed to create EQs: %d\n", err); +@@ -3680,7 +3682,6 @@ int mana_probe(struct gdma_dev *gd, bool resuming) + if (!err) + err = add_adev(gd, "eth"); + +- INIT_DELAYED_WORK(&ac->gf_stats_work, mana_gf_stats_work_handler); + schedule_delayed_work(&ac->gf_stats_work, MANA_GF_STATS_PERIOD); + + out: +-- +2.53.0 + diff --git a/queue-6.18/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-6.18/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..cb79f36314 --- /dev/null +++ b/queue-6.18/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 84fdece72e4abd0776c9b289d39009f968162c0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 73650200482f4..40149edecbd5a 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -219,16 +219,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -376,7 +374,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -401,7 +399,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -501,7 +499,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -512,7 +510,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-6.18/rtla-fix-parse_cpu_set-bug-introduced-by-strtoi.patch b/queue-6.18/rtla-fix-parse_cpu_set-bug-introduced-by-strtoi.patch new file mode 100644 index 0000000000..7dae26a972 --- /dev/null +++ b/queue-6.18/rtla-fix-parse_cpu_set-bug-introduced-by-strtoi.patch @@ -0,0 +1,59 @@ +From 2051bfa8625375bdd32101e5a456e014d3630716 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Jan 2026 21:26:41 +0200 +Subject: rtla: Fix parse_cpu_set() bug introduced by strtoi() + +From: Costa Shulyupin + +[ Upstream commit 6ea8a206108fe8b5940c2797afc54ae9f5a7bbdd ] + +The patch 'Replace atoi() with a robust strtoi()' introduced a bug +in parse_cpu_set(), which relies on partial parsing of the input string. + +The function parses CPU specifications like '0-3,5' by incrementing +a pointer through the string. strtoi() rejects strings with trailing +characters, causing parse_cpu_set() to fail on any CPU list with +multiple entries. + +Restore the original use of atoi() in parse_cpu_set(). + +Fixes: 7e9dfccf8f11 ("rtla: Replace atoi() with a robust strtoi()") +Signed-off-by: Costa Shulyupin +Reviewed-by: Masami Hiramatsu (Google) +Link: https://lore.kernel.org/r/20260112192642.212848-2-costa.shul@redhat.com +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/src/utils.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c +index bf20077cca742..b4cd93f784522 100644 +--- a/tools/tracing/rtla/src/utils.c ++++ b/tools/tracing/rtla/src/utils.c +@@ -113,18 +113,16 @@ int parse_cpu_set(char *cpu_list, cpu_set_t *set) + nr_cpus = sysconf(_SC_NPROCESSORS_CONF); + + for (p = cpu_list; *p; ) { +- if (strtoi(p, &cpu)) +- goto err; +- if (cpu < 0 || cpu >= nr_cpus) ++ cpu = atoi(p); ++ if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus) + goto err; + + while (isdigit(*p)) + p++; + if (*p == '-') { + p++; +- if (strtoi(p, &end_cpu)) +- goto err; +- if (end_cpu < cpu || end_cpu >= nr_cpus) ++ end_cpu = atoi(p); ++ if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus) + goto err; + while (isdigit(*p)) + p++; +-- +2.53.0 + diff --git a/queue-6.18/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch b/queue-6.18/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch new file mode 100644 index 0000000000..1bc1ca601c --- /dev/null +++ b/queue-6.18/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch @@ -0,0 +1,57 @@ +From f6b2068d8eba96851cf3a48c365d6e833ec3a21b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 May 2026 12:45:03 +0200 +Subject: sched/fair: Fix wakeup_preempt_fair() for not waking up task + +From: Vincent Guittot + +[ Upstream commit 9f6d929ee2c6f0266edb564bcd2bd47fd6e884a8 ] + +Make sure to only call pick_next_entity() on an non-empty cfs_rq. + +The assumption that p is always enqueued and not delayed, is only true for +wakeup. If p was moved while delayed, pick_next_entity() will dequeue it and +the cfs might become empty. Test if there are still queued tasks before trying +again to determine if p could be the next one to be picked. + +There are at least 2 cases: + +When cfs becomes idle, it tries to pull tasks but if those pulled tasks are +delayed, they will be dequeued when attached to cfs. attach_tasks() -> +attach_task() -> wakeup_preempt(rq, p, 0); + +A misfit task running on cfs A triggers a load balance to be pulled on a better +cpu, the load balance on cfs B starts an active load balance to pulled the +running misfit task. If there is a delayed dequeue task on cfs A, it can be +pulled instead of the previously running misfit task. attach_one_task() -> +attach_task() -> wakeup_preempt(rq, p, 0); + +Fixes: ac8e69e69363 ("sched/fair: Fix wakeup_preempt_fair() vs delayed dequeue") +Signed-off-by: Vincent Guittot +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20260503104503.1732682-1-vincent.guittot@linaro.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 565a96d6811e7..58f535cc64215 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8985,9 +8985,10 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int + + /* + * Because p is enqueued, nse being null can only mean that we +- * dequeued a delayed task. ++ * dequeued a delayed task. If there are still entities queued in ++ * cfs, check if the next one will be p. + */ +- if (!nse) ++ if (!nse && cfs_rq->nr_queued) + goto pick; + + if (sched_feat(RUN_TO_PARITY)) +-- +2.53.0 + diff --git a/queue-6.18/sched-fair-revert-force-wakeup-preemption.patch b/queue-6.18/sched-fair-revert-force-wakeup-preemption.patch new file mode 100644 index 0000000000..ad95ef14ce --- /dev/null +++ b/queue-6.18/sched-fair-revert-force-wakeup-preemption.patch @@ -0,0 +1,63 @@ +From 67f63df3067e4501aac3b17c308562d85456992e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Jan 2026 11:28:58 +0100 +Subject: sched/fair: Revert force wakeup preemption + +From: Vincent Guittot + +[ Upstream commit 15257cc2f905dbf5813c0bfdd3c15885f28093c4 ] + +This agressively bypasses run_to_parity and slice protection with the +assumpiton that this is what waker wants but there is no garantee that +the wakee will be the next to run. It is a better choice to use +yield_to_task or WF_SYNC in such case. + +This increases the number of resched and preemption because a task becomes +quickly "ineligible" when it runs; We update the task vruntime periodically +and before the task exhausted its slice or at least quantum. + +Example: +2 tasks A and B wake up simultaneously with lag = 0. Both are +eligible. Task A runs 1st and wakes up task C. Scheduler updates task +A's vruntime which becomes greater than average runtime as all others +have a lag == 0 and didn't run yet. Now task A is ineligible because +it received more runtime than the other task but it has not yet +exhausted its slice nor a min quantum. We force preemption, disable +protection but Task B will run 1st not task C. + +Sidenote, DELAY_ZERO increases this effect by clearing positive lag at +wake up. + +Fixes: e837456fdca8 ("sched/fair: Reimplement NEXT_BUDDY to align with EEVDF goals") +Signed-off-by: Vincent Guittot +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20260123102858.52428-1-vincent.guittot@linaro.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 58f535cc64215..7e0e2044d840b 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8943,16 +8943,6 @@ static void check_preempt_wakeup_fair(struct rq *rq, struct task_struct *p, int + if ((wake_flags & WF_FORK) || pse->sched_delayed) + return; + +- /* +- * If @p potentially is completing work required by current then +- * consider preemption. +- * +- * Reschedule if waker is no longer eligible. */ +- if (in_task() && !entity_eligible(cfs_rq, se)) { +- preempt_action = PREEMPT_WAKEUP_RESCHED; +- goto preempt; +- } +- + /* Prefer picking wakee soon if appropriate. */ + if (sched_feat(NEXT_BUDDY) && + set_preempt_buddy(cfs_rq, wake_flags, pse, se)) { +-- +2.53.0 + diff --git a/queue-6.18/series b/queue-6.18/series index 19ccc2e75c..5be957956d 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -860,3 +860,19 @@ futex-drop-clone_thread-requirement-for-private-defa.patch revert-pseries-papr-hvpipe-fix-race-with-interrupt-h.patch revert-papr-hvpipe-convert-papr_hvpipe_dev_create_ha.patch pci-initialize-temporary-device-in-new_id_store.patch +erofs-fix-offset-truncation-when-shifting-pgoff-on-3.patch +bpf-fix-sync_linked_regs-regarding-bpf_add_const32-z.patch +net-airoha-fix-a-copy-and-paste-bug-in-probe.patch +fuse-fix-race-when-disposing-stale-dentries.patch +fuse-make-sure-dentry-is-evicted-if-stale.patch +rtla-fix-parse_cpu_set-bug-introduced-by-strtoi.patch +net-airoha-move-entries-to-queue-head-in-case-of-dma.patch +net-airoha-move-ndesc-initialization-at-end-of-airoh.patch-22905 +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +net-airoha-remove-code-duplication-in-airoha_regs.h.patch +net-airoha-use-gdm-port-enum-value-whenever-possible.patch +net-airoha-fix-vip-configuration-for-an7583-soc.patch +net-mana-fix-use-after-free-in-reset-service-rescan-.patch +net-mana-init-gf_stats_work-before-potential-error-p.patch +sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch +sched-fair-revert-force-wakeup-preemption.patch diff --git a/queue-6.6/bonding-fix-null-pointer-dereference-in-actor_port_p.patch b/queue-6.6/bonding-fix-null-pointer-dereference-in-actor_port_p.patch new file mode 100644 index 0000000000..412efbc1c8 --- /dev/null +++ b/queue-6.6/bonding-fix-null-pointer-dereference-in-actor_port_p.patch @@ -0,0 +1,65 @@ +From c84c3a1f3bac1864a6fdb79748e153c87229902b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 07:26:20 +0000 +Subject: bonding: fix NULL pointer dereference in actor_port_prio setting +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hangbin Liu + +[ Upstream commit 067bf016e99ad72aa4ff869d6dec1fd62a9c6202 ] + +Liang reported an issue where setting a slave’s actor_port_prio to +predefined values such as 0, 255, or 65535 would cause a system crash. + +The problem occurs because in bond_opt_parse(), when the provided value +matches a predefined table entry, the function returns that table entry, +which does not contain slave information. Later, in +bond_option_actor_port_prio_set(), calling bond_slave_get_rtnl() leads +to a NULL pointer dereference. + +Since actor_port_prio is defined as a u16 and initialized to the default +value of 255 in ad_initialize_port(), there is no need for the +bond_actor_port_prio_tbl. Using the BOND_OPTFLAG_RAWVAL flag is sufficient. + +Fixes: 6b6dc81ee7e8 ("bonding: add support for per-port LACP actor priority") +Reported-by: Liang Li +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251105072620.164841-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/bonding/bond_options.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index f4ad0fc624c98..5b6c01b31f985 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -225,13 +225,6 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = { + { NULL, -1, 0}, + }; + +-static const struct bond_opt_value bond_actor_port_prio_tbl[] = { +- { "minval", 0, BOND_VALFLAG_MIN}, +- { "maxval", 65535, BOND_VALFLAG_MAX}, +- { "default", 255, BOND_VALFLAG_DEFAULT}, +- { NULL, -1, 0}, +-}; +- + static const struct bond_opt_value bond_ad_user_port_key_tbl[] = { + { "minval", 0, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, + { "maxval", 1023, BOND_VALFLAG_MAX}, +@@ -497,7 +490,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { + .id = BOND_OPT_ACTOR_PORT_PRIO, + .name = "actor_port_prio", + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), +- .values = bond_actor_port_prio_tbl, ++ .flags = BOND_OPTFLAG_RAWVAL, + .set = bond_option_actor_port_prio_set, + }, + [BOND_OPT_AD_ACTOR_SYSTEM] = { +-- +2.53.0 + diff --git a/queue-6.6/ksmbd-validate-response-sizes-in-ipc_validate_msg.patch b/queue-6.6/ksmbd-validate-response-sizes-in-ipc_validate_msg.patch new file mode 100644 index 0000000000..a3eac30ca0 --- /dev/null +++ b/queue-6.6/ksmbd-validate-response-sizes-in-ipc_validate_msg.patch @@ -0,0 +1,129 @@ +From c706eca1842187766745bd9eef676488cbbdb691 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Apr 2026 07:25:00 -0400 +Subject: ksmbd: validate response sizes in ipc_validate_msg() + +From: Michael Bommarito + +[ Upstream commit d6a6aa81eac2c9bff66dc6e191179cb69a14426b ] + +ipc_validate_msg() computes the expected message size for each +response type by adding (or multiplying) attacker-controlled fields +from the daemon response to a fixed struct size in unsigned int +arithmetic. Three cases can overflow: + + KSMBD_EVENT_RPC_REQUEST: + msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz; + KSMBD_EVENT_SHARE_CONFIG_REQUEST: + msg_sz = sizeof(struct ksmbd_share_config_response) + + resp->payload_sz; + KSMBD_EVENT_LOGIN_REQUEST_EXT: + msg_sz = sizeof(struct ksmbd_login_response_ext) + + resp->ngroups * sizeof(gid_t); + +resp->payload_sz is __u32 and resp->ngroups is __s32. Each addition +can wrap in unsigned int; the multiplication by sizeof(gid_t) mixes +signed and size_t, so a negative ngroups is converted to SIZE_MAX +before the multiply. A wrapped value of msg_sz that happens to +equal entry->msg_sz bypasses the size check on the next line, and +downstream consumers (smb2pdu.c:6742 memcpy using rpc_resp->payload_sz, +kmemdup in ksmbd_alloc_user using resp_ext->ngroups) then trust the +unverified length. + +Use check_add_overflow() on the RPC_REQUEST and SHARE_CONFIG_REQUEST +paths to detect integer overflow without constraining functional +payload size; userspace ksmbd-tools grows NDR responses in 4096-byte +chunks for calls like NetShareEnumAll, so a hard transport cap is +unworkable on the response side. For LOGIN_REQUEST_EXT, reject +resp->ngroups outside the signed [0, NGROUPS_MAX] range up front and +report the error from ipc_validate_msg() so it fires at the IPC +boundary; with that bound the subsequent multiplication and addition +stay well below UINT_MAX. The now-redundant ngroups check and +pr_err in ksmbd_alloc_user() are removed. + +This is the response-side analogue of aab98e2dbd64 ("ksmbd: fix +integer overflows on 32 bit systems"), which hardened the request +side. + +Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") +Fixes: a77e0e02af1c ("ksmbd: add support for supplementary groups") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-6 +Assisted-by: Codex:gpt-5-4 +Signed-off-by: Michael Bommarito +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/mgmt/user_config.c | 6 ------ + fs/smb/server/transport_ipc.c | 16 +++++++++++++--- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/fs/smb/server/mgmt/user_config.c b/fs/smb/server/mgmt/user_config.c +index 421a4a95e216a..e9b3a8e049668 100644 +--- a/fs/smb/server/mgmt/user_config.c ++++ b/fs/smb/server/mgmt/user_config.c +@@ -56,12 +56,6 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, + goto err_free; + + if (resp_ext) { +- if (resp_ext->ngroups > NGROUPS_MAX) { +- pr_err("ngroups(%u) from login response exceeds max groups(%d)\n", +- resp_ext->ngroups, NGROUPS_MAX); +- goto err_free; +- } +- + user->sgid = kmemdup(resp_ext->____payload, + resp_ext->ngroups * sizeof(gid_t), + GFP_KERNEL); +diff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c +index f0f93f76bc43d..554a6c92a1ccb 100644 +--- a/fs/smb/server/transport_ipc.c ++++ b/fs/smb/server/transport_ipc.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + #include "vfs_cache.h" + #include "transport_ipc.h" +@@ -497,7 +498,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) + { + struct ksmbd_rpc_command *resp = entry->response; + +- msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz; ++ if (check_add_overflow(sizeof(struct ksmbd_rpc_command), ++ resp->payload_sz, &msg_sz)) ++ return -EINVAL; + break; + } + case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST: +@@ -516,8 +519,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) + if (resp->payload_sz < resp->veto_list_sz) + return -EINVAL; + +- msg_sz = sizeof(struct ksmbd_share_config_response) + +- resp->payload_sz; ++ if (check_add_overflow(sizeof(struct ksmbd_share_config_response), ++ resp->payload_sz, &msg_sz)) ++ return -EINVAL; + } + break; + } +@@ -526,6 +530,12 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) + struct ksmbd_login_response_ext *resp = entry->response; + + if (resp->ngroups) { ++ if (resp->ngroups < 0 || ++ resp->ngroups > NGROUPS_MAX) { ++ pr_err("ngroups(%d) from login response exceeds max groups(%d)\n", ++ resp->ngroups, NGROUPS_MAX); ++ return -EINVAL; ++ } + msg_sz = sizeof(struct ksmbd_login_response_ext) + + resp->ngroups * sizeof(gid_t); + } +-- +2.53.0 + diff --git a/queue-6.6/net-bcmgenet-fix-leaking-free_bds.patch b/queue-6.6/net-bcmgenet-fix-leaking-free_bds.patch new file mode 100644 index 0000000000..5aa347e0d0 --- /dev/null +++ b/queue-6.6/net-bcmgenet-fix-leaking-free_bds.patch @@ -0,0 +1,49 @@ +From 5c5be7ef88829ef70be9362ca59e793f738a1514 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Apr 2026 10:57:55 -0700 +Subject: net: bcmgenet: fix leaking free_bds + +From: Justin Chen + +[ Upstream commit 3f3168300efb839028328d720ab3962f91d6a0d0 ] + +While reclaiming the tx queue we fast forward the write pointer to +drop any data in flight. These dropped frames are not added back +to the pool of free bds. We also need to tell the netdev that we +are dropping said data. + +Fixes: f1bacae8b655 ("net: bcmgenet: support reclaiming unsent Tx packets") +Signed-off-by: Justin Chen +Reviewed-by: Florian Fainelli +Reviewed-by: Nicolai Buchwitz +Tested-by: Nicolai Buchwitz +Link: https://patch.msgid.link/20260406175756.134567-3-justin.chen@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index d9bd011e0d7c8..d1f5ae56fa417 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1942,6 +1942,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + drop = (ring->prod_index - ring->c_index) & DMA_C_INDEX_MASK; + released += drop; + ring->prod_index = ring->c_index & DMA_C_INDEX_MASK; ++ ring->free_bds += drop; + while (drop--) { + cb_ptr = bcmgenet_put_txcb(priv, ring); + skb = cb_ptr->skb; +@@ -1953,6 +1954,7 @@ static unsigned int bcmgenet_tx_reclaim(struct net_device *dev, + } + if (skb) + dev_consume_skb_any(skb); ++ netdev_tx_reset_queue(netdev_get_tx_queue(dev, ring->index)); + bcmgenet_tdma_ring_writel(priv, ring->index, + ring->prod_index, TDMA_PROD_INDEX); + wr_ptr = ring->write_ptr * WORDS_PER_BD(priv); +-- +2.53.0 + diff --git a/queue-6.6/net-bcmgenet-initialize-u64-stats-seq-counter.patch b/queue-6.6/net-bcmgenet-initialize-u64-stats-seq-counter.patch new file mode 100644 index 0000000000..0ac1304dad --- /dev/null +++ b/queue-6.6/net-bcmgenet-initialize-u64-stats-seq-counter.patch @@ -0,0 +1,82 @@ +From 3ce823818f9e0a9ee618a76bd7b6f7b6250e9786 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Jul 2025 18:24:17 +0900 +Subject: net: bcmgenet: Initialize u64 stats seq counter + +From: Ryo Takakura + +[ Upstream commit ffc2c8c4a714df53a715827d6334ab9474424f6a ] + +Initialize u64 stats as it uses seq counter on 32bit machines +as suggested by lockdep below. + +[ 1.830953][ T1] INFO: trying to register non-static key. +[ 1.830993][ T1] The code is fine but needs lockdep annotation, or maybe +[ 1.831027][ T1] you didn't initialize this object before use? +[ 1.831057][ T1] turning off the locking correctness validator. +[ 1.831090][ T1] CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 6.16.0-rc2-v7l+ #1 PREEMPT +[ 1.831097][ T1] Tainted: [W]=WARN +[ 1.831099][ T1] Hardware name: BCM2711 +[ 1.831101][ T1] Call trace: +[ 1.831104][ T1] unwind_backtrace from show_stack+0x18/0x1c +[ 1.831120][ T1] show_stack from dump_stack_lvl+0x8c/0xcc +[ 1.831129][ T1] dump_stack_lvl from register_lock_class+0x9e8/0x9fc +[ 1.831141][ T1] register_lock_class from __lock_acquire+0x420/0x22c0 +[ 1.831154][ T1] __lock_acquire from lock_acquire+0x130/0x3f8 +[ 1.831166][ T1] lock_acquire from bcmgenet_get_stats64+0x4a4/0x4c8 +[ 1.831176][ T1] bcmgenet_get_stats64 from dev_get_stats+0x4c/0x408 +[ 1.831184][ T1] dev_get_stats from rtnl_fill_stats+0x38/0x120 +[ 1.831193][ T1] rtnl_fill_stats from rtnl_fill_ifinfo+0x7f8/0x1890 +[ 1.831203][ T1] rtnl_fill_ifinfo from rtmsg_ifinfo_build_skb+0xd0/0x138 +[ 1.831214][ T1] rtmsg_ifinfo_build_skb from rtmsg_ifinfo+0x48/0x8c +[ 1.831225][ T1] rtmsg_ifinfo from register_netdevice+0x8c0/0x95c +[ 1.831237][ T1] register_netdevice from register_netdev+0x28/0x40 +[ 1.831247][ T1] register_netdev from bcmgenet_probe+0x690/0x6bc +[ 1.831255][ T1] bcmgenet_probe from platform_probe+0x64/0xbc +[ 1.831263][ T1] platform_probe from really_probe+0xd0/0x2d4 +[ 1.831269][ T1] really_probe from __driver_probe_device+0x90/0x1a4 +[ 1.831273][ T1] __driver_probe_device from driver_probe_device+0x38/0x11c +[ 1.831278][ T1] driver_probe_device from __driver_attach+0x9c/0x18c +[ 1.831282][ T1] __driver_attach from bus_for_each_dev+0x84/0xd4 +[ 1.831291][ T1] bus_for_each_dev from bus_add_driver+0xd4/0x1f4 +[ 1.831303][ T1] bus_add_driver from driver_register+0x88/0x120 +[ 1.831312][ T1] driver_register from do_one_initcall+0x78/0x360 +[ 1.831320][ T1] do_one_initcall from kernel_init_freeable+0x2bc/0x314 +[ 1.831331][ T1] kernel_init_freeable from kernel_init+0x1c/0x144 +[ 1.831339][ T1] kernel_init from ret_from_fork+0x14/0x20 +[ 1.831344][ T1] Exception stack(0xf082dfb0 to 0xf082dff8) +[ 1.831349][ T1] dfa0: 00000000 00000000 00000000 00000000 +[ 1.831353][ T1] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 1.831356][ T1] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 + +Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics") +Reviewed-by: Florian Fainelli +Signed-off-by: Ryo Takakura +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250702092417.46486-1-ryotkkr98@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index e08abde4685ac..d9bd011e0d7c8 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -4084,6 +4084,12 @@ static int bcmgenet_probe(struct platform_device *pdev) + for (i = 0; i <= priv->hw_params->rx_queues; i++) + priv->rx_rings[i].rx_max_coalesced_frames = 1; + ++ /* Initialize u64 stats seq counter for 32bit machines */ ++ for (i = 0; i <= priv->hw_params->rx_queues; i++) ++ u64_stats_init(&priv->rx_rings[i].stats64.syncp); ++ for (i = 0; i <= priv->hw_params->tx_queues; i++) ++ u64_stats_init(&priv->tx_rings[i].stats64.syncp); ++ + /* libphy will determine the link state */ + netif_carrier_off(dev); + +-- +2.53.0 + diff --git a/queue-6.6/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-6.6/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..e885c53de4 --- /dev/null +++ b/queue-6.6/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 5b35ee02ebd6237b6bc41ce3b87d9e5f74403bd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 4c69b44fc3aa8..6ca4dd77a29c7 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -212,16 +212,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -369,7 +367,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -394,7 +392,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -493,7 +491,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -504,7 +502,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-6.6/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch b/queue-6.6/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch new file mode 100644 index 0000000000..413fa283f6 --- /dev/null +++ b/queue-6.6/netconsole-avoid-out-of-bounds-access-on-empty-strin.patch @@ -0,0 +1,58 @@ +From ff1e27e9dc8d110682e6f11e7b49b17b3e32d5e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Apr 2026 03:18:36 -0700 +Subject: netconsole: avoid out-of-bounds access on empty string in + trim_newline() + +From: Breno Leitao + +[ Upstream commit 7079c8c13f2d33992bc846240517d88f4ab07781 ] + +trim_newline() unconditionally dereferences s[len - 1] after computing +len = strnlen(s, maxlen). When the string is empty, len is 0 and the +expression underflows to s[(size_t)-1], reading (and potentially +writing) one byte before the buffer. + +The two callers feed trim_newline() with the result of strscpy() from +configfs store callbacks (dev_name_store, userdatum_value_store). +configfs guarantees count >= 1 reaches the callback, but the byte +itself can be NUL: a userspace write(fd, "\0", 1) leaves the +destination empty after strscpy() and triggers the underflow. The OOB +write only fires if the adjacent byte happens to be '\n', so this is +not a security issue, but the access is undefined behaviour either way. + +This pattern is commonly flagged by LLM-based code reviewers. While it +is not a security fix, the underlying access is undefined behaviour and +the change is small and self-contained, so it is a reasonable candidate +for the stable trees. + +Guard the dereference on a non-zero length. + +Fixes: ae001dc67907 ("net: netconsole: move newline trimming to function") +Cc: stable@vger.kernel.org +Signed-off-by: Breno Leitao +Reviewed-by: Gustavo Luiz Duarte +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-netcons_trim_newline-v1-1-dc35889aeedf@debian.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/netconsole.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c +index f58643bdafc5c..fffffa3658d22 100644 +--- a/drivers/net/netconsole.c ++++ b/drivers/net/netconsole.c +@@ -278,6 +278,8 @@ static void trim_newline(char *s, size_t maxlen) + size_t len; + + len = strnlen(s, maxlen); ++ if (!len) ++ return; + if (s[len - 1] == '\n') + s[len - 1] = '\0'; + } +-- +2.53.0 + diff --git a/queue-6.6/series b/queue-6.6/series index a98f40cde6..02d04935c9 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -442,3 +442,9 @@ revert-crypto-nx-migrate-to-scomp-api.patch smb-client-correctly-handle-errorcontextdata-as-a-fl.patch smb-client-fix-oob-reads-parsing-symlink-error-respo.patch crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-a.patch +net-bcmgenet-initialize-u64-stats-seq-counter.patch +net-bcmgenet-fix-leaking-free_bds.patch +ksmbd-validate-response-sizes-in-ipc_validate_msg.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +netconsole-avoid-out-of-bounds-access-on-empty-strin.patch +bonding-fix-null-pointer-dereference-in-actor_port_p.patch diff --git a/queue-7.0/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch b/queue-7.0/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch new file mode 100644 index 0000000000..37bb1b3702 --- /dev/null +++ b/queue-7.0/net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch @@ -0,0 +1,82 @@ +From 5e80348c92c3ae66ef25ffb436b5bd74412b089a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Apr 2026 08:00:56 +0000 +Subject: net/sched: sch_pie: annotate more data-races in pie_dump_stats() + +From: Eric Dumazet + +[ Upstream commit 6d4106e8df94c0c52cf3ca6a6a0d01567fb3844e ] + +My prior patch missed few READ_ONCE()/WRITE_ONCE() annotations. + +Fixes: 5154561d9b11 ("net/sched: sch_pie: annotate data-races in pie_dump_stats()") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20260430080056.35104-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/sch_pie.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c +index 73650200482f4..40149edecbd5a 100644 +--- a/net/sched/sch_pie.c ++++ b/net/sched/sch_pie.c +@@ -219,16 +219,14 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params, + * packet timestamp. + */ + if (!params->dq_rate_estimator) { +- vars->qdelay = now - pie_get_enqueue_time(skb); ++ WRITE_ONCE(vars->qdelay, ++ backlog ? now - pie_get_enqueue_time(skb) : 0); + + if (vars->dq_tstamp != DTIME_INVALID) + dtime = now - vars->dq_tstamp; + + vars->dq_tstamp = now; + +- if (backlog == 0) +- vars->qdelay = 0; +- + if (dtime == 0) + return; + +@@ -376,7 +374,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC))) + delta += MAX_PROB / (100 / 2); + +- vars->prob += delta; ++ WRITE_ONCE(vars->prob, vars->prob + delta); + + if (delta > 0) { + /* prevent overflow */ +@@ -401,7 +399,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars, + + if (qdelay == 0 && qdelay_old == 0 && update_prob) + /* Reduce drop probability to 98.4% */ +- vars->prob -= vars->prob / 64; ++ WRITE_ONCE(vars->prob, vars->prob - vars->prob / 64); + + WRITE_ONCE(vars->qdelay, qdelay); + vars->backlog_old = backlog; +@@ -501,7 +499,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + { + struct pie_sched_data *q = qdisc_priv(sch); + struct tc_pie_xstats st = { +- .prob = q->vars.prob << BITS_PER_BYTE, ++ .prob = READ_ONCE(q->vars.prob) << BITS_PER_BYTE, + .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) / + NSEC_PER_USEC, + .packets_in = READ_ONCE(q->stats.packets_in), +@@ -512,7 +510,7 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) + }; + + /* avg_dq_rate is only valid if dq_rate_estimator is enabled */ +- st.dq_rate_estimating = q->params.dq_rate_estimator; ++ st.dq_rate_estimating = READ_ONCE(q->params.dq_rate_estimator); + + /* unscale and return dq_rate in bytes per sec */ + if (st.dq_rate_estimating) +-- +2.53.0 + diff --git a/queue-7.0/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch b/queue-7.0/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch new file mode 100644 index 0000000000..954a9a1a7f --- /dev/null +++ b/queue-7.0/sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch @@ -0,0 +1,57 @@ +From 8748462319f2ee8808db49698067efafde296160 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 3 May 2026 12:45:03 +0200 +Subject: sched/fair: Fix wakeup_preempt_fair() for not waking up task + +From: Vincent Guittot + +[ Upstream commit 9f6d929ee2c6f0266edb564bcd2bd47fd6e884a8 ] + +Make sure to only call pick_next_entity() on an non-empty cfs_rq. + +The assumption that p is always enqueued and not delayed, is only true for +wakeup. If p was moved while delayed, pick_next_entity() will dequeue it and +the cfs might become empty. Test if there are still queued tasks before trying +again to determine if p could be the next one to be picked. + +There are at least 2 cases: + +When cfs becomes idle, it tries to pull tasks but if those pulled tasks are +delayed, they will be dequeued when attached to cfs. attach_tasks() -> +attach_task() -> wakeup_preempt(rq, p, 0); + +A misfit task running on cfs A triggers a load balance to be pulled on a better +cpu, the load balance on cfs B starts an active load balance to pulled the +running misfit task. If there is a delayed dequeue task on cfs A, it can be +pulled instead of the previously running misfit task. attach_one_task() -> +attach_task() -> wakeup_preempt(rq, p, 0); + +Fixes: ac8e69e69363 ("sched/fair: Fix wakeup_preempt_fair() vs delayed dequeue") +Signed-off-by: Vincent Guittot +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20260503104503.1732682-1-vincent.guittot@linaro.org +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 87200a22b3169..3bce48ad0bc5a 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8922,9 +8922,10 @@ static void wakeup_preempt_fair(struct rq *rq, struct task_struct *p, int wake_f + + /* + * Because p is enqueued, nse being null can only mean that we +- * dequeued a delayed task. ++ * dequeued a delayed task. If there are still entities queued in ++ * cfs, check if the next one will be p. + */ +- if (!nse) ++ if (!nse && cfs_rq->nr_queued) + goto pick; + + if (sched_feat(RUN_TO_PARITY)) +-- +2.53.0 + diff --git a/queue-7.0/series b/queue-7.0/series index 4a997294a1..a57726fc53 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -1035,3 +1035,6 @@ kselftest-arm64-include-asm-ptrace.h-for-user_gcs-de.patch arm64-reserve-an-extra-page-for-early-kernel-mapping.patch futex-drop-clone_thread-requirement-for-private-defa.patch pci-initialize-temporary-device-in-new_id_store.patch +workqueue-fix-devm_alloc_workqueue-va_list-misuse.patch +net-sched-sch_pie-annotate-more-data-races-in-pie_du.patch +sched-fair-fix-wakeup_preempt_fair-for-not-waking-up.patch diff --git a/queue-7.0/workqueue-fix-devm_alloc_workqueue-va_list-misuse.patch b/queue-7.0/workqueue-fix-devm_alloc_workqueue-va_list-misuse.patch new file mode 100644 index 0000000000..06fa41dcc9 --- /dev/null +++ b/queue-7.0/workqueue-fix-devm_alloc_workqueue-va_list-misuse.patch @@ -0,0 +1,141 @@ +From 1b53fcd03f7cef1b4a56c929bc6ae3386305e611 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Apr 2026 08:10:43 -0700 +Subject: workqueue: fix devm_alloc_workqueue() va_list misuse + +From: Breno Leitao + +[ Upstream commit 0de4cb473aed57ee4ba7e0551ad27bddc19fc519 ] + +devm_alloc_workqueue() built a va_list and passed it as a single +positional argument to the variadic alloc_workqueue() macro: + + va_start(args, max_active); + wq = alloc_workqueue(fmt, flags, max_active, args); + va_end(args); + +C does not allow forwarding a va_list through a ... parameter. +alloc_workqueue() expands to alloc_workqueue_noprof(), which runs +its own va_start() over its ... params, so the inner +vsnprintf(wq->name, sizeof(wq->name), fmt, args) in +__alloc_workqueue() received the outer va_list object as the first +variadic slot rather than the caller's actual format arguments. + +Add a new static helper alloc_workqueue_va() that wraps +__alloc_workqueue() and runs wq_init_lockdep() on success, and +fold both alloc_workqueue_noprof() and devm_alloc_workqueue_noprof() +onto it as suggested by Tejun. + +The wq_init_lockdep() step is required on the devm path +too, otherwise __flush_workqueue()'s on-stack +COMPLETION_INITIALIZER_ONSTACK_MAP would NULL-deref wq->lockdep_map. + +No caller changes are required. devm_alloc_ordered_workqueue() is +a macro forwarding to devm_alloc_workqueue() and inherits the fix. +Two in-tree callers actively trigger the broken path on every probe: + + drivers/power/supply/mt6370-charger.c:889 + drivers/power/supply/max77705_charger.c:649 + +both of which use devm_alloc_ordered_workqueue(dev, "%s", 0, +dev_name(dev)). + +A standalone reproducer module is available at[1]. + +Link: https://github.com/leitao/debug/blob/main/workqueue/valist/wq_va_test.c [1] +Fixes: 1dfc9d60a69e ("workqueue: devres: Add device-managed allocate workqueue") +Signed-off-by: Breno Leitao +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + include/linux/workqueue.h | 6 ++++-- + kernel/workqueue.c | 28 +++++++++++++++++++--------- + 2 files changed, 23 insertions(+), 11 deletions(-) + +diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h +index f8d235aef10dd..218557a8f7577 100644 +--- a/include/linux/workqueue.h ++++ b/include/linux/workqueue.h +@@ -529,8 +529,10 @@ alloc_workqueue_noprof(const char *fmt, unsigned int flags, int max_active, ...) + * Pointer to the allocated workqueue on success, %NULL on failure. + */ + __printf(2, 5) struct workqueue_struct * +-devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags, +- int max_active, ...); ++devm_alloc_workqueue_noprof(struct device *dev, const char *fmt, ++ unsigned int flags, int max_active, ...); ++#define devm_alloc_workqueue(...) \ ++ alloc_hooks(devm_alloc_workqueue_noprof(__VA_ARGS__)) + + #ifdef CONFIG_LOCKDEP + /** +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index e57040931d8b7..5d704df76a946 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5885,6 +5885,20 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, + return NULL; + } + ++static struct workqueue_struct *alloc_workqueue_va(const char *fmt, ++ unsigned int flags, ++ int max_active, ++ va_list args) ++{ ++ struct workqueue_struct *wq; ++ ++ wq = __alloc_workqueue(fmt, flags, max_active, args); ++ if (wq) ++ wq_init_lockdep(wq); ++ ++ return wq; ++} ++ + __printf(1, 4) + struct workqueue_struct *alloc_workqueue_noprof(const char *fmt, + unsigned int flags, +@@ -5894,12 +5908,8 @@ struct workqueue_struct *alloc_workqueue_noprof(const char *fmt, + va_list args; + + va_start(args, max_active); +- wq = __alloc_workqueue(fmt, flags, max_active, args); ++ wq = alloc_workqueue_va(fmt, flags, max_active, args); + va_end(args); +- if (!wq) +- return NULL; +- +- wq_init_lockdep(wq); + + return wq; + } +@@ -5911,15 +5921,15 @@ static void devm_workqueue_release(void *res) + } + + __printf(2, 5) struct workqueue_struct * +-devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags, +- int max_active, ...) ++devm_alloc_workqueue_noprof(struct device *dev, const char *fmt, ++ unsigned int flags, int max_active, ...) + { + struct workqueue_struct *wq; + va_list args; + int ret; + + va_start(args, max_active); +- wq = alloc_workqueue(fmt, flags, max_active, args); ++ wq = alloc_workqueue_va(fmt, flags, max_active, args); + va_end(args); + if (!wq) + return NULL; +@@ -5930,7 +5940,7 @@ devm_alloc_workqueue(struct device *dev, const char *fmt, unsigned int flags, + + return wq; + } +-EXPORT_SYMBOL_GPL(devm_alloc_workqueue); ++EXPORT_SYMBOL_GPL(devm_alloc_workqueue_noprof); + + #ifdef CONFIG_LOCKDEP + __printf(1, 5) +-- +2.53.0 +