--- /dev/null
+From stable+bounces-236109-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:55 -0400
+Subject: arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage to 0.81V
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Martin Kepplinger <martin.kepplinger@puri.sm>, Shawn Guo <shawnguo@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-2-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 94b91e3ca6688fafd6a5dd70bd89fe9d3aee88da ]
+
+0.8V is outside of the operating voltage specified for imx8mq, see
+chapter 3.1.4 "Operating ranges" of the IMX8MDQLQCEC document.
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -706,7 +706,7 @@
+ regulator-ramp-delay = <1250>;
+ rohm,dvs-run-voltage = <880000>;
+ rohm,dvs-idle-voltage = <820000>;
+- rohm,dvs-suspend-voltage = <800000>;
++ rohm,dvs-suspend-voltage = <810000>;
+ regulator-always-on;
+ };
+
--- /dev/null
+From stable+bounces-236111-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:57 -0400
+Subject: arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-4-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 511f76bf1dce5acf8907b65a7d1bc8f7e7c0d637 ]
+
+The minimal voltage of VDD_SOC sourced from BUCK1 is 0.81V, which
+is the currently set value. However, BD71837 only guarantees accuracy
+of ±0.01V, and this still doesn't factor other reasons for actual
+voltage to slightly drop in, resulting in the possibility of running
+out of the operational range.
+
+Bump the voltage up to 0.85V, which should give enough headroom.
+
+Cc: stable@vger.kernel.org
+Fixes: 8f0216b006e5 ("arm64: dts: Add a device tree for the Librem 5 phone")
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -706,7 +706,7 @@
+ regulator-ramp-delay = <1250>;
+ rohm,dvs-run-voltage = <900000>;
+ rohm,dvs-idle-voltage = <850000>;
+- rohm,dvs-suspend-voltage = <810000>;
++ rohm,dvs-suspend-voltage = <850000>;
+ regulator-always-on;
+ };
+
--- /dev/null
+From stable+bounces-236108-greg=kroah.com@vger.kernel.org Mon Apr 13 16:27:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:54 -0400
+Subject: arm64: dts: imx8mq-librem5: Set the DVS voltages lower
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Martin Kepplinger <martin.kepplinger@puri.sm>, Shawn Guo <shawnguo@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-1-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit c24a9b698fb02cd0723fa8375abab07f94b97b10 ]
+
+They're still in the operating range according to i.MX 8M Quad
+datasheet. There's some headroom added over minimal values to
+account for voltage drop.
+
+Operational ranges (min - typ - max [selected]):
+ - VDD_SOC (BUCK1): 0.81 - 0.9 - 0.99 [0.88]
+ - VDD_ARM (BUCK2): 0.81 - 0.9 - 1.05 [0.84] (1000MHz)
+ 0.90 - 1.0 - 1.05 [0.93] (1500MHz)
+ - VDD_GPU (BUCK3): 0.81 - 0.9 - 1.05 [0.85] (800MHz)
+ 0.90 - 1.0 - 1.05 [ -- ] (1000MHz)
+ - VDD_VPU (BUCK4): 0.81 - 0.9 - 1.05 [ -- ] (550/500/588MHz)
+ 0.90 - 1.0 - 1.05 [0.93] (660/600/800MHz)
+
+Idle power consumption doesn't appear to be influenced much,
+but a simple load test (`cat /dev/urandom | pigz - > /dev/null`
+combined with running Animatch) seems to show about 0.3W of
+difference.
+
+Care is advised, as there may be differences between each
+units in how low can they be undervolted - in my experience,
+reaching that point usually makes the phone fail to boot.
+In my case, it appears that my Birch phone can go down the most.
+
+This is a somewhat conservative set of values that I've seen
+working well on all my devices; I haven't tried very hard to
+optimize it, so more experiments are welcome.
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 2 -
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 22 ++++++++++++++------
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -12,7 +12,7 @@
+
+ &a53_opp_table {
+ opp-1000000000 {
+- opp-microvolt = <1000000>;
++ opp-microvolt = <950000>;
+ };
+ };
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -704,8 +704,8 @@
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-ramp-delay = <1250>;
+- rohm,dvs-run-voltage = <900000>;
+- rohm,dvs-idle-voltage = <850000>;
++ rohm,dvs-run-voltage = <880000>;
++ rohm,dvs-idle-voltage = <820000>;
+ rohm,dvs-suspend-voltage = <800000>;
+ regulator-always-on;
+ };
+@@ -716,8 +716,8 @@
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-ramp-delay = <1250>;
+- rohm,dvs-run-voltage = <1000000>;
+- rohm,dvs-idle-voltage = <900000>;
++ rohm,dvs-run-voltage = <950000>;
++ rohm,dvs-idle-voltage = <850000>;
+ regulator-always-on;
+ };
+
+@@ -726,14 +726,14 @@
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+- rohm,dvs-run-voltage = <900000>;
++ rohm,dvs-run-voltage = <850000>;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+- rohm,dvs-run-voltage = <1000000>;
++ rohm,dvs-run-voltage = <930000>;
+ };
+
+ buck5_reg: BUCK5 {
+@@ -1214,3 +1214,13 @@
+ fsl,ext-reset-output;
+ status = "okay";
+ };
++
++&a53_opp_table {
++ opp-1000000000 {
++ opp-microvolt = <850000>;
++ };
++
++ opp-1500000000 {
++ opp-microvolt = <950000>;
++ };
++};
--- /dev/null
+From stable+bounces-239239-greg=kroah.com@vger.kernel.org Mon Apr 20 18:53:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:41:57 -0400
+Subject: fs/ocfs2: fix comments mentioning i_mutex
+To: stable@vger.kernel.org
+Cc: hongnanli <hongnan.li@linux.alibaba.com>, Joseph Qi <joseph.qi@linux.alibaba.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Gang He <ghe@suse.com>, Jun Piao <piaojun@huawei.com>, Andrew Morton <akpm@linux-foundation.org>, Linus Torvalds <torvalds@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420144158.1143438-1-sashal@kernel.org>
+
+From: hongnanli <hongnan.li@linux.alibaba.com>
+
+[ Upstream commit 137cebf9432eae024d0334953ed92a2a78619b52 ]
+
+inode->i_mutex has been replaced with inode->i_rwsem long ago. Fix
+comments still mentioning i_mutex.
+
+Link: https://lkml.kernel.org/r/20220214031314.100094-1-hongnan.li@linux.alibaba.com
+Signed-off-by: hongnanli <hongnan.li@linux.alibaba.com>
+Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: b02da26a992d ("ocfs2: fix possible deadlock between unlink and dio_end_io_write")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/alloc.c | 2 +-
+ fs/ocfs2/aops.c | 2 +-
+ fs/ocfs2/cluster/nodemanager.c | 2 +-
+ fs/ocfs2/dir.c | 4 ++--
+ fs/ocfs2/file.c | 4 ++--
+ fs/ocfs2/inode.c | 2 +-
+ fs/ocfs2/localalloc.c | 6 +++---
+ fs/ocfs2/namei.c | 2 +-
+ fs/ocfs2/ocfs2.h | 4 ++--
+ fs/ocfs2/quota_global.c | 2 +-
+ fs/ocfs2/xattr.c | 2 +-
+ 11 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/fs/ocfs2/alloc.c
++++ b/fs/ocfs2/alloc.c
+@@ -5986,7 +5986,7 @@ bail:
+ return status;
+ }
+
+-/* Expects you to already be holding tl_inode->i_mutex */
++/* Expects you to already be holding tl_inode->i_rwsem */
+ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
+ {
+ int status;
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -2324,7 +2324,7 @@ static int ocfs2_dio_end_io_write(struct
+
+ down_write(&oi->ip_alloc_sem);
+
+- /* Delete orphan before acquire i_mutex. */
++ /* Delete orphan before acquire i_rwsem. */
+ if (dwc->dw_orphaned) {
+ BUG_ON(dwc->dw_writer_pid != task_pid_nr(current));
+
+--- a/fs/ocfs2/cluster/nodemanager.c
++++ b/fs/ocfs2/cluster/nodemanager.c
+@@ -689,7 +689,7 @@ static struct config_group *o2nm_cluster
+ struct o2nm_node_group *ns = NULL;
+ struct config_group *o2hb_group = NULL, *ret = NULL;
+
+- /* this runs under the parent dir's i_mutex; there can be only
++ /* this runs under the parent dir's i_rwsem; there can be only
+ * one caller in here at a time */
+ if (o2nm_single_cluster)
+ return ERR_PTR(-ENOSPC);
+--- a/fs/ocfs2/dir.c
++++ b/fs/ocfs2/dir.c
+@@ -1979,7 +1979,7 @@ bail_nolock:
+ }
+
+ /*
+- * NOTE: this should always be called with parent dir i_mutex taken.
++ * NOTE: this should always be called with parent dir i_rwsem taken.
+ */
+ int ocfs2_find_files_on_disk(const char *name,
+ int namelen,
+@@ -2026,7 +2026,7 @@ int ocfs2_lookup_ino_from_name(struct in
+ * Return -EEXIST if the directory contains the name
+ * Return -EFSCORRUPTED if found corruption
+ *
+- * Callers should have i_mutex + a cluster lock on dir
++ * Callers should have i_rwsem + a cluster lock on dir
+ */
+ int ocfs2_check_dir_for_entry(struct inode *dir,
+ const char *name,
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -270,7 +270,7 @@ int ocfs2_update_inode_atime(struct inod
+
+ /*
+ * Don't use ocfs2_mark_inode_dirty() here as we don't always
+- * have i_mutex to guard against concurrent changes to other
++ * have i_rwsem to guard against concurrent changes to other
+ * inode fields.
+ */
+ inode->i_atime = current_time(inode);
+@@ -1068,7 +1068,7 @@ static int ocfs2_extend_file(struct inod
+ /*
+ * The alloc sem blocks people in read/write from reading our
+ * allocation until we're done changing it. We depend on
+- * i_mutex to block other extend/truncate calls while we're
++ * i_rwsem to block other extend/truncate calls while we're
+ * here. We even have to hold it for sparse files because there
+ * might be some tail zeroing.
+ */
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -713,7 +713,7 @@ bail:
+ /*
+ * Serialize with orphan dir recovery. If the process doing
+ * recovery on this orphan dir does an iget() with the dir
+- * i_mutex held, we'll deadlock here. Instead we detect this
++ * i_rwsem held, we'll deadlock here. Instead we detect this
+ * and exit early - recovery will wipe this inode for us.
+ */
+ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb,
+--- a/fs/ocfs2/localalloc.c
++++ b/fs/ocfs2/localalloc.c
+@@ -606,7 +606,7 @@ out:
+
+ /*
+ * make sure we've got at least bits_wanted contiguous bits in the
+- * local alloc. You lose them when you drop i_mutex.
++ * local alloc. You lose them when you drop i_rwsem.
+ *
+ * We will add ourselves to the transaction passed in, but may start
+ * our own in order to shift windows.
+@@ -636,7 +636,7 @@ int ocfs2_reserve_local_alloc_bits(struc
+
+ /*
+ * We must double check state and allocator bits because
+- * another process may have changed them while holding i_mutex.
++ * another process may have changed them while holding i_rwsem.
+ */
+ spin_lock(&osb->osb_lock);
+ if (!ocfs2_la_state_enabled(osb) ||
+@@ -1029,7 +1029,7 @@ enum ocfs2_la_event {
+ /*
+ * Given an event, calculate the size of our next local alloc window.
+ *
+- * This should always be called under i_mutex of the local alloc inode
++ * This should always be called under i_rwsem of the local alloc inode
+ * so that local alloc disabling doesn't race with processes trying to
+ * use the allocator.
+ *
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -485,7 +485,7 @@ leave:
+ ocfs2_free_alloc_context(meta_ac);
+
+ /*
+- * We should call iput after the i_mutex of the bitmap been
++ * We should call iput after the i_rwsem of the bitmap been
+ * unlocked in ocfs2_free_alloc_context, or the
+ * ocfs2_delete_inode will mutex_lock again.
+ */
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -369,7 +369,7 @@ struct ocfs2_super
+ struct delayed_work la_enable_wq;
+
+ /*
+- * Must hold local alloc i_mutex and osb->osb_lock to change
++ * Must hold local alloc i_rwsem and osb->osb_lock to change
+ * local_alloc_bits. Reads can be done under either lock.
+ */
+ unsigned int local_alloc_bits;
+@@ -444,7 +444,7 @@ struct ocfs2_super
+ atomic_t osb_tl_disable;
+ /*
+ * How many clusters in our truncate log.
+- * It must be protected by osb_tl_inode->i_mutex.
++ * It must be protected by osb_tl_inode->i_rwsem.
+ */
+ unsigned int truncated_clusters;
+
+--- a/fs/ocfs2/quota_global.c
++++ b/fs/ocfs2/quota_global.c
+@@ -36,7 +36,7 @@
+ * should be obeyed by all the functions:
+ * - any write of quota structure (either to local or global file) is protected
+ * by dqio_sem or dquot->dq_lock.
+- * - any modification of global quota file holds inode cluster lock, i_mutex,
++ * - any modification of global quota file holds inode cluster lock, i_rwsem,
+ * and ip_alloc_sem of the global quota file (achieved by
+ * ocfs2_lock_global_qf). It also has to hold qinfo_lock.
+ * - an allocation of new blocks for local quota file is protected by
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -7208,7 +7208,7 @@ out:
+ * Used for reflink a non-preserve-security file.
+ *
+ * It uses common api like ocfs2_xattr_set, so the caller
+- * must not hold any lock expect i_mutex.
++ * must not hold any lock expect i_rwsem.
+ */
+ int ocfs2_init_security_and_acl(struct inode *dir,
+ struct inode *inode,
--- /dev/null
+From stable+bounces-239966-greg=kroah.com@vger.kernel.org Mon Apr 20 20:27:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:29:31 -0400
+Subject: mm: blk-cgroup: fix use-after-free in cgwb_release_workfn()
+To: stable@vger.kernel.org
+Cc: Breno Leitao <leitao@debian.org>, Dennis Zhou <dennis@kernel.org>, Shakeel Butt <shakeel.butt@linux.dev>, David Hildenbrand <david@kernel.org>, Jens Axboe <axboe@kernel.dk>, Johannes Weiner <hannes@cmpxchg.org>, Josef Bacik <josef@toxicpanda.com>, JP Kobryn <inwardvessel@gmail.com>, Liam Howlett <liam.howlett@oracle.com>, "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>, Martin KaFai Lau <martin.lau@linux.dev>, Michal Hocko <mhocko@suse.com>, Mike Rapoport <rppt@kernel.org>, Suren Baghdasaryan <surenb@google.com>, Tejun Heo <tj@kernel.org>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420172931.1421876-1-sashal@kernel.org>
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 8f5857be99f1ed1fa80991c72449541f634626ee ]
+
+cgwb_release_workfn() calls css_put(wb->blkcg_css) and then later accesses
+wb->blkcg_css again via blkcg_unpin_online(). If css_put() drops the last
+reference, the blkcg can be freed asynchronously (css_free_rwork_fn ->
+blkcg_css_free -> kfree) before blkcg_unpin_online() dereferences the
+pointer to access blkcg->online_pin, resulting in a use-after-free:
+
+ BUG: KASAN: slab-use-after-free in blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
+ Write of size 4 at addr ff11000117aa6160 by task kworker/71:1/531
+ Workqueue: cgwb_release cgwb_release_workfn
+ Call Trace:
+ <TASK>
+ blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
+ cgwb_release_workfn (mm/backing-dev.c:629)
+ process_scheduled_works (kernel/workqueue.c:3278 kernel/workqueue.c:3385)
+
+ Freed by task 1016:
+ kfree (./include/linux/kasan.h:235 mm/slub.c:2689 mm/slub.c:6246 mm/slub.c:6561)
+ css_free_rwork_fn (kernel/cgroup/cgroup.c:5542)
+ process_scheduled_works (kernel/workqueue.c:3302 kernel/workqueue.c:3385)
+
+** Stack based on commit 66672af7a095 ("Add linux-next specific files
+for 20260410")
+
+I am seeing this crash sporadically in Meta fleet across multiple kernel
+versions. A full reproducer is available at:
+https://github.com/leitao/debug/blob/main/reproducers/repro_blkcg_uaf.sh
+
+(The race window is narrow. To make it easily reproducible, inject a
+msleep(100) between css_put() and blkcg_unpin_online() in
+cgwb_release_workfn(). With that delay and a KASAN-enabled kernel, the
+reproducer triggers the splat reliably in less than a second.)
+
+Fix this by moving blkcg_unpin_online() before css_put(), so the
+cgwb's CSS reference keeps the blkcg alive while blkcg_unpin_online()
+accesses it.
+
+Link: https://lore.kernel.org/20260413-blkcg-v1-1-35b72622d16c@debian.org
+Fixes: 59b57717fff8 ("blkcg: delay blkg destruction until after writeback has finished")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Dennis Zhou <dennis@kernel.org>
+Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Josef Bacik <josef@toxicpanda.com>
+Cc: JP Kobryn <inwardvessel@gmail.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/backing-dev.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/mm/backing-dev.c
++++ b/mm/backing-dev.c
+@@ -404,12 +404,13 @@ static void cgwb_release_workfn(struct w
+ wb_shutdown(wb);
+
+ css_put(wb->memcg_css);
+- css_put(wb->blkcg_css);
+- mutex_unlock(&wb->bdi->cgwb_release_mutex);
+
+ /* triggers blkg destruction if no online users left */
+ blkcg_unpin_online(blkcg);
+
++ css_put(wb->blkcg_css);
++ mutex_unlock(&wb->bdi->cgwb_release_mutex);
++
+ fprop_local_destroy_percpu(&wb->memcg_completions);
+
+ spin_lock_irq(&cgwb_lock);
--- /dev/null
+From stable+bounces-233086-greg=kroah.com@vger.kernel.org Thu Apr 2 19:42:24 2026
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Thu, 2 Apr 2026 19:42:01 +0200
+Subject: MPTCP: fix lock class name family in pm_nl_create_listen_socket
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: MPTCP Upstream <mptcp@lists.linux.dev>, Li Xiasong <lixiasong1@huawei.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20260402174200.3474039-2-matttbe@kernel.org>
+
+From: Li Xiasong <lixiasong1@huawei.com>
+
+commit 7ab4a7c5d969642782b8a5b608da0dd02aa9f229 upstream.
+
+In mptcp_pm_nl_create_listen_socket(), use entry->addr.family
+instead of sk->sk_family for lock class setup. The 'sk' parameter
+is a netlink socket, not the MPTCP subflow socket being created.
+
+Fixes: cee4034a3db1 ("mptcp: fix lockdep false positive in mptcp_pm_nl_create_listen_socket()")
+Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260319112159.3118874-1-lixiasong1@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflict in pm_kernel.c, because commit 8617e85e04bd ("mptcp: pm:
+ split in-kernel PM specific code") is not in this version, and moves
+ code from pm_netlink.c to pm_kernel.c. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1041,7 +1041,7 @@ static struct lock_class_key mptcp_keys[
+ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
+ struct mptcp_pm_addr_entry *entry)
+ {
+- bool is_ipv6 = sk->sk_family == AF_INET6;
++ bool is_ipv6 = entry->addr.family == AF_INET6;
+ int addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_storage addr;
+ struct socket *ssock;
--- /dev/null
+From stable+bounces-230415-greg=kroah.com@vger.kernel.org Thu Mar 26 04:18:23 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Thu, 26 Mar 2026 11:18:02 +0800
+Subject: netdevsim: Fix memory leak of nsim_dev->fa_cookie
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Wang Yufen <wangyufen@huawei.com>, Jiri Pirko <jiri@mellanox.com>, Jakub Kicinski <kuba@kernel.org>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260326031802.2410719-1-johnny_haocn@sina.com>
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit 064bc7312bd09a48798418663090be0c776183db ]
+
+kmemleak reports this issue:
+
+unreferenced object 0xffff8881bac872d0 (size 8):
+ comm "sh", pid 58603, jiffies 4481524462 (age 68.065s)
+ hex dump (first 8 bytes):
+ 04 00 00 00 de ad be ef ........
+ backtrace:
+ [<00000000c80b8577>] __kmalloc+0x49/0x150
+ [<000000005292b8c6>] nsim_dev_trap_fa_cookie_write+0xc1/0x210 [netdevsim]
+ [<0000000093d78e77>] full_proxy_write+0xf3/0x180
+ [<000000005a662c16>] vfs_write+0x1c5/0xaf0
+ [<000000007aabf84a>] ksys_write+0xed/0x1c0
+ [<000000005f1d2e47>] do_syscall_64+0x3b/0x90
+ [<000000006001c6ec>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The issue occurs in the following scenarios:
+
+nsim_dev_trap_fa_cookie_write()
+ kmalloc() fa_cookie
+ nsim_dev->fa_cookie = fa_cookie
+..
+nsim_drv_remove()
+
+The fa_cookie allocked in nsim_dev_trap_fa_cookie_write() is not freed. To
+fix, add kfree(nsim_dev->fa_cookie) to nsim_drv_remove().
+
+Fixes: d3cbb907ae57 ("netdevsim: add ACL trap reporting cookie as a metadata")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Cc: Jiri Pirko <jiri@mellanox.com>
+Link: https://lore.kernel.org/r/1668504625-14698-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ The context change is due to the commit 5e388f3dc38c
+("netdevsim: move vfconfig to nsim_dev") in v5.16
+which is irrelevant to the logic of this patch. ]
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/netdevsim/dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -1582,6 +1582,7 @@ void nsim_dev_remove(struct nsim_bus_dev
+ ARRAY_SIZE(nsim_devlink_params));
+ devlink_unregister(devlink);
+ devlink_resources_unregister(devlink, NULL);
++ kfree(nsim_dev->fa_cookie);
+ devlink_free(devlink);
+ }
+
--- /dev/null
+From 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 13 Feb 2024 16:23:38 +0100
+Subject: netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream.
+
+pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL
+but pointer is invalid).
+
+Rework this to not call slab allocator when we'd request a 0-byte
+allocation.
+
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+[Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in
+pipapo_clone() still relies on `src->rules` rather than `src->rules_alloc`
+(introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously
+backported INT_MAX clamping check uses `src->rules`. This patch correctly
+moves that `src->rules > (INT_MAX / ...)` check inside the new
+`if (src->rules > 0)` block]
+Signed-off-by: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_set_pipapo.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_ge
+ int i;
+
+ m = priv->clone;
++ if (m->bsize_max == 0)
++ return ret;
+
+ res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC);
+ if (!res_map) {
+@@ -1365,14 +1367,20 @@ static struct nft_pipapo_match *pipapo_c
+ src->bsize * sizeof(*dst->lt) *
+ src->groups * NFT_PIPAPO_BUCKETS(src->bb));
+
+- if (src->rules > (INT_MAX / sizeof(*src->mt)))
+- goto out_mt;
++ if (src->rules > 0) {
++ if (src->rules > (INT_MAX / sizeof(*src->mt)))
++ goto out_mt;
++
++ dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt),
++ GFP_KERNEL);
++ if (!dst->mt)
++ goto out_mt;
+
+- dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL);
+- if (!dst->mt)
+- goto out_mt;
++ memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
++ } else {
++ dst->mt = NULL;
++ }
+
+- memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
+ src++;
+ dst++;
+ }
--- /dev/null
+From stable+bounces-236156-greg=kroah.com@vger.kernel.org Mon Apr 13 17:56:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:23 -0400
+Subject: ocfs2: add inline inode consistency check to ocfs2_validate_inode_block()
+To: stable@vger.kernel.org
+Cc: Dmitry Antipov <dmantipov@yandex.ru>, syzbot+c16daba279a1161acfb0@syzkaller.appspotmail.com, Joseph Qi <joseph.qi@linux.alibaba.com>, Joseph Qi <jiangqi903@gmail.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-1-sashal@kernel.org>
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a2b1c419ff72ec62ff5831684e30cd1d4f0b09ee ]
+
+In 'ocfs2_validate_inode_block()', add an extra check whether an inode
+with inline data (i.e. self-contained) has no clusters, thus preventing
+an invalid inode from being passed to 'ocfs2_evict_inode()' and below.
+
+Link: https://lkml.kernel.org/r/20251023141650.417129-1-dmantipov@yandex.ru
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Reported-by: syzbot+c16daba279a1161acfb0@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c16daba279a1161acfb0
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 7bc5da4842be ("ocfs2: fix out-of-bounds write in ocfs2_write_end_inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1416,6 +1416,14 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
++ if ((le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) &&
++ le32_to_cpu(di->i_clusters)) {
++ rc = ocfs2_error(sb, "Invalid dinode %llu: %u clusters\n",
++ (unsigned long long)bh->b_blocknr,
++ le32_to_cpu(di->i_clusters));
++ goto bail;
++ }
++
+ rc = 0;
+
+ bail:
--- /dev/null
+From stable+bounces-236158-greg=kroah.com@vger.kernel.org Mon Apr 13 17:50:34 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:25 -0400
+Subject: ocfs2: fix out-of-bounds write in ocfs2_write_end_inline
+To: stable@vger.kernel.org
+Cc: Joseph Qi <joseph.qi@linux.alibaba.com>, syzbot+62c1793956716ea8b28a@syzkaller.appspotmail.com, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-3-sashal@kernel.org>
+
+From: Joseph Qi <joseph.qi@linux.alibaba.com>
+
+[ Upstream commit 7bc5da4842bed3252d26e742213741a4d0ac1b14 ]
+
+KASAN reports a use-after-free write of 4086 bytes in
+ocfs2_write_end_inline, called from ocfs2_write_end_nolock during a
+copy_file_range splice fallback on a corrupted ocfs2 filesystem mounted on
+a loop device. The actual bug is an out-of-bounds write past the inode
+block buffer, not a true use-after-free. The write overflows into an
+adjacent freed page, which KASAN reports as UAF.
+
+The root cause is that ocfs2_try_to_write_inline_data trusts the on-disk
+id_count field to determine whether a write fits in inline data. On a
+corrupted filesystem, id_count can exceed the physical maximum inline data
+capacity, causing writes to overflow the inode block buffer.
+
+Call trace (crash path):
+
+ vfs_copy_file_range (fs/read_write.c:1634)
+ do_splice_direct
+ splice_direct_to_actor
+ iter_file_splice_write
+ ocfs2_file_write_iter
+ generic_perform_write
+ ocfs2_write_end
+ ocfs2_write_end_nolock (fs/ocfs2/aops.c:1949)
+ ocfs2_write_end_inline (fs/ocfs2/aops.c:1915)
+ memcpy_from_folio <-- KASAN: write OOB
+
+So add id_count upper bound check in ocfs2_validate_inode_block() to
+alongside the existing i_size check to fix it.
+
+Link: https://lkml.kernel.org/r/20260403063830.3662739-1-joseph.qi@linux.alibaba.com
+Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reported-by: syzbot+62c1793956716ea8b28a@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=62c1793956716ea8b28a
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1427,6 +1427,16 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
++ if (le16_to_cpu(data->id_count) >
++ ocfs2_max_inline_data_with_xattr(sb, di)) {
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: inline data id_count %u exceeds max %d\n",
++ (unsigned long long)bh->b_blocknr,
++ le16_to_cpu(data->id_count),
++ ocfs2_max_inline_data_with_xattr(sb, di));
++ goto bail;
++ }
++
+ if (le64_to_cpu(di->i_size) > le16_to_cpu(data->id_count)) {
+ rc = ocfs2_error(sb,
+ "Invalid dinode #%llu: inline data i_size %llu exceeds id_count %u\n",
--- /dev/null
+From stable+bounces-239240-greg=kroah.com@vger.kernel.org Mon Apr 20 17:35:05 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:41:58 -0400
+Subject: ocfs2: fix possible deadlock between unlink and dio_end_io_write
+To: stable@vger.kernel.org
+Cc: Joseph Qi <joseph.qi@linux.alibaba.com>, syzbot+67b90111784a3eac8c04@syzkaller.appspotmail.com, Heming Zhao <heming.zhao@suse.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Joseph Qi <jiangqi903@gmail.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420144158.1143438-2-sashal@kernel.org>
+
+From: Joseph Qi <joseph.qi@linux.alibaba.com>
+
+[ Upstream commit b02da26a992db0c0e2559acbda0fc48d4a2fd337 ]
+
+ocfs2_unlink takes orphan dir inode_lock first and then ip_alloc_sem,
+while in ocfs2_dio_end_io_write, it acquires these locks in reverse order.
+This creates an ABBA lock ordering violation on lock classes
+ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE] and
+ocfs2_file_ip_alloc_sem_key.
+
+Lock Chain #0 (orphan dir inode_lock -> ip_alloc_sem):
+ocfs2_unlink
+ ocfs2_prepare_orphan_dir
+ ocfs2_lookup_lock_orphan_dir
+ inode_lock(orphan_dir_inode) <- lock A
+ __ocfs2_prepare_orphan_dir
+ ocfs2_prepare_dir_for_insert
+ ocfs2_extend_dir
+ ocfs2_expand_inline_dir
+ down_write(&oi->ip_alloc_sem) <- Lock B
+
+Lock Chain #1 (ip_alloc_sem -> orphan dir inode_lock):
+ocfs2_dio_end_io_write
+ down_write(&oi->ip_alloc_sem) <- Lock B
+ ocfs2_del_inode_from_orphan()
+ inode_lock(orphan_dir_inode) <- Lock A
+
+Deadlock Scenario:
+ CPU0 (unlink) CPU1 (dio_end_io_write)
+ ------ ------
+ inode_lock(orphan_dir_inode)
+ down_write(ip_alloc_sem)
+ down_write(ip_alloc_sem)
+ inode_lock(orphan_dir_inode)
+
+Since ip_alloc_sem is to protect allocation changes, which is unrelated
+with operations in ocfs2_del_inode_from_orphan. So move
+ocfs2_del_inode_from_orphan out of ip_alloc_sem to fix the deadlock.
+
+Link: https://lkml.kernel.org/r/20260306032211.1016452-1-joseph.qi@linux.alibaba.com
+Reported-by: syzbot+67b90111784a3eac8c04@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=67b90111784a3eac8c04
+Fixes: a86a72a4a4e0 ("ocfs2: take ip_alloc_sem in ocfs2_dio_get_block & ocfs2_dio_end_io_write")
+Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/aops.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -2322,8 +2322,6 @@ static int ocfs2_dio_end_io_write(struct
+ goto out;
+ }
+
+- down_write(&oi->ip_alloc_sem);
+-
+ /* Delete orphan before acquire i_rwsem. */
+ if (dwc->dw_orphaned) {
+ BUG_ON(dwc->dw_writer_pid != task_pid_nr(current));
+@@ -2336,6 +2334,7 @@ static int ocfs2_dio_end_io_write(struct
+ mlog_errno(ret);
+ }
+
++ down_write(&oi->ip_alloc_sem);
+ di = (struct ocfs2_dinode *)di_bh->b_data;
+
+ ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
--- /dev/null
+From stable+bounces-236157-greg=kroah.com@vger.kernel.org Mon Apr 13 17:50:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:24 -0400
+Subject: ocfs2: validate inline data i_size during inode read
+To: stable@vger.kernel.org
+Cc: Deepanshu Kartikey <kartikey406@gmail.com>, syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com, Joseph Qi <joseph.qi@linux.alibaba.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-2-sashal@kernel.org>
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 1524af3685b35feac76662cc551cbc37bd14775f ]
+
+When reading an inode from disk, ocfs2_validate_inode_block() performs
+various sanity checks but does not validate the size of inline data. If
+the filesystem is corrupted, an inode's i_size can exceed the actual
+inline data capacity (id_count).
+
+This causes ocfs2_dir_foreach_blk_id() to iterate beyond the inline data
+buffer, triggering a use-after-free when accessing directory entries from
+freed memory.
+
+In the syzbot report:
+ - i_size was 1099511627576 bytes (~1TB)
+ - Actual inline data capacity (id_count) is typically <256 bytes
+ - A garbage rec_len (54648) caused ctx->pos to jump out of bounds
+ - This triggered a UAF in ocfs2_check_dir_entry()
+
+Fix by adding a validation check in ocfs2_validate_inode_block() to ensure
+inodes with inline data have i_size <= id_count. This catches the
+corruption early during inode read and prevents all downstream code from
+operating on invalid data.
+
+Link: https://lkml.kernel.org/r/20251212052132.16750-1-kartikey406@gmail.com
+Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
+Reported-by: syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c897823f699449cc3eb4
+Tested-by: syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20251211115231.3560028-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20251212040400.6377-1-kartikey406@gmail.com/T/ [v2]
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 7bc5da4842be ("ocfs2: fix out-of-bounds write in ocfs2_write_end_inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1416,12 +1416,25 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
+- if ((le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) &&
+- le32_to_cpu(di->i_clusters)) {
+- rc = ocfs2_error(sb, "Invalid dinode %llu: %u clusters\n",
+- (unsigned long long)bh->b_blocknr,
+- le32_to_cpu(di->i_clusters));
+- goto bail;
++ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {
++ struct ocfs2_inline_data *data = &di->id2.i_data;
++
++ if (le32_to_cpu(di->i_clusters)) {
++ rc = ocfs2_error(sb,
++ "Invalid dinode %llu: %u clusters\n",
++ (unsigned long long)bh->b_blocknr,
++ le32_to_cpu(di->i_clusters));
++ goto bail;
++ }
++
++ if (le64_to_cpu(di->i_size) > le16_to_cpu(data->id_count)) {
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: inline data i_size %llu exceeds id_count %u\n",
++ (unsigned long long)bh->b_blocknr,
++ (unsigned long long)le64_to_cpu(di->i_size),
++ le16_to_cpu(data->id_count));
++ goto bail;
++ }
+ }
+
+ rc = 0;
--- /dev/null
+From 521bd39d9d28ce54cbfec7f9b89c94ad4fdb8350 Mon Sep 17 00:00:00 2001
+From: Hari Bathini <hbathini@linux.ibm.com>
+Date: Tue, 3 Mar 2026 23:40:25 +0530
+Subject: powerpc64/bpf: do not increment tailcall count when prog is NULL
+
+From: Hari Bathini <hbathini@linux.ibm.com>
+
+commit 521bd39d9d28ce54cbfec7f9b89c94ad4fdb8350 upstream.
+
+Do not increment tailcall count, if tailcall did not succeed due to
+missing BPF program.
+
+Fixes: ce0761419fae ("powerpc/bpf: Implement support for tail calls")
+Cc: stable@vger.kernel.org
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260303181031.390073-2-hbathini@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ Conflicts due to missing clean up commits
+ b10cb163c4b3 ("powerpc64/bpf elfv2: Setup kernel TOC in r2 on entry")
+ 49c3af43e65f ("powerpc/bpf: Simplify bpf_to_ppc() and adopt it for powerpc64")
+ 036d559c0bde ("powerpc/bpf: Use _Rn macros for GPRs")
+ and missing feature commit 2ed2d8f6fb38 ("powerpc64/bpf: Support
+ tailcalls with subprogs") resolved accordingly. ]
+Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
+---
+ arch/powerpc/net/bpf_jit_comp64.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/arch/powerpc/net/bpf_jit_comp64.c
++++ b/arch/powerpc/net/bpf_jit_comp64.c
+@@ -239,30 +239,32 @@ static int bpf_jit_emit_tail_call(u32 *i
+ * tail_call_cnt++;
+ */
+ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1));
+- PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
+
+ /* prog = array->ptrs[index]; */
+- EMIT(PPC_RAW_MULI(b2p[TMP_REG_1], b2p_index, 8));
+- EMIT(PPC_RAW_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array));
+- PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_array, ptrs));
++ EMIT(PPC_RAW_MULI(b2p[TMP_REG_2], b2p_index, 8));
++ EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p_bpf_array));
++ PPC_BPF_LL(b2p[TMP_REG_2], b2p[TMP_REG_2], offsetof(struct bpf_array, ptrs));
+
+ /*
+ * if (prog == NULL)
+ * goto out;
+ */
+- EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_1], 0));
++ EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_2], 0));
+ PPC_BCC(COND_EQ, out);
+
+ /* goto *(prog->bpf_func + prologue_size); */
+- PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_prog, bpf_func));
++ PPC_BPF_LL(b2p[TMP_REG_2], b2p[TMP_REG_2], offsetof(struct bpf_prog, bpf_func));
+ #ifdef PPC64_ELF_ABI_v1
+ /* skip past the function descriptor */
+- EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1],
++ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_2], b2p[TMP_REG_2],
+ FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE));
+ #else
+- EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE));
++ EMIT(PPC_RAW_ADDI(b2p[TMP_REG_2], b2p[TMP_REG_2], BPF_TAILCALL_PROLOGUE_SIZE));
+ #endif
+- EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_1]));
++ EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_2]));
++
++ /* Writeback updated tailcall count */
++ PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
+
+ /* tear down stack, restore NVRs, ... */
+ bpf_jit_emit_common_epilogue(image, ctx);
--- /dev/null
+From stable+bounces-236110-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:56 -0400
+Subject: Revert "arm64: dts: imx8mq-librem5: Set the DVS voltages lower"
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-3-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 4cd46ea0eb4504f7f4fea92cb4601c5c9a3e545e ]
+
+This reverts commit c24a9b698fb02cd0723fa8375abab07f94b97b10.
+
+It's been found that there's a significant per-unit variance in accepted
+supply voltages and the current set still makes some units unstable.
+
+Revert back to nominal values.
+
+Cc: stable@vger.kernel.org
+Fixes: c24a9b698fb0 ("arm64: dts: imx8mq-librem5: Set the DVS voltages lower")
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts | 2 -
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 22 +++++---------------
+ 2 files changed, 7 insertions(+), 17 deletions(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -12,7 +12,7 @@
+
+ &a53_opp_table {
+ opp-1000000000 {
+- opp-microvolt = <950000>;
++ opp-microvolt = <1000000>;
+ };
+ };
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -704,8 +704,8 @@
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-ramp-delay = <1250>;
+- rohm,dvs-run-voltage = <880000>;
+- rohm,dvs-idle-voltage = <820000>;
++ rohm,dvs-run-voltage = <900000>;
++ rohm,dvs-idle-voltage = <850000>;
+ rohm,dvs-suspend-voltage = <810000>;
+ regulator-always-on;
+ };
+@@ -716,8 +716,8 @@
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+ regulator-ramp-delay = <1250>;
+- rohm,dvs-run-voltage = <950000>;
+- rohm,dvs-idle-voltage = <850000>;
++ rohm,dvs-run-voltage = <1000000>;
++ rohm,dvs-idle-voltage = <900000>;
+ regulator-always-on;
+ };
+
+@@ -726,14 +726,14 @@
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-boot-on;
+- rohm,dvs-run-voltage = <850000>;
++ rohm,dvs-run-voltage = <900000>;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "buck4";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+- rohm,dvs-run-voltage = <930000>;
++ rohm,dvs-run-voltage = <1000000>;
+ };
+
+ buck5_reg: BUCK5 {
+@@ -1214,13 +1214,3 @@
+ fsl,ext-reset-output;
+ status = "okay";
+ };
+-
+-&a53_opp_table {
+- opp-1000000000 {
+- opp-microvolt = <850000>;
+- };
+-
+- opp-1500000000 {
+- opp-microvolt = <950000>;
+- };
+-};
--- /dev/null
+From stable+bounces-237697-greg=kroah.com@vger.kernel.org Tue Apr 14 03:35:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 21:35:02 -0400
+Subject: rxrpc: Fix call removal to use RCU safe deletion
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Linus Torvalds <torvalds@linux-foundation.org>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414013502.3857050-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 ]
+
+Fix rxrpc call removal from the rxnet->calls list to use list_del_rcu()
+rather than list_del_init() to prevent stuffing up reading
+/proc/net/rxrpc/calls from potentially getting into an infinite loop.
+
+This, however, means that list_empty() no longer works on an entry that's
+been deleted from the list, making it harder to detect prior deletion. Fix
+this by:
+
+Firstly, make rxrpc_destroy_all_calls() only dump the first ten calls that
+are unexpectedly still on the list. Limiting the number of steps means
+there's no need to call cond_resched() or to remove calls from the list
+here, thereby eliminating the need for rxrpc_put_call() to check for that.
+
+rxrpc_put_call() can then be fixed to unconditionally delete the call from
+the list as it is the only place that the deletion occurs.
+
+Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Linus Torvalds <torvalds@linux-foundation.org>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted to older API ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/call_object.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -634,11 +634,9 @@ void rxrpc_put_call(struct rxrpc_call *c
+ _debug("call %d dead", call->debug_id);
+ ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
+
+- if (!list_empty(&call->link)) {
+- spin_lock_bh(&rxnet->call_lock);
+- list_del_init(&call->link);
+- spin_unlock_bh(&rxnet->call_lock);
+- }
++ spin_lock_bh(&rxnet->call_lock);
++ list_del_rcu(&call->link);
++ spin_unlock_bh(&rxnet->call_lock);
+
+ rxrpc_cleanup_call(call);
+ }
+@@ -709,24 +707,20 @@ void rxrpc_destroy_all_calls(struct rxrp
+ _enter("");
+
+ if (!list_empty(&rxnet->calls)) {
+- spin_lock_bh(&rxnet->call_lock);
++ int shown = 0;
+
+- while (!list_empty(&rxnet->calls)) {
+- call = list_entry(rxnet->calls.next,
+- struct rxrpc_call, link);
+- _debug("Zapping call %p", call);
++ spin_lock_bh(&rxnet->call_lock);
+
++ list_for_each_entry(call, &rxnet->calls, link) {
+ rxrpc_see_call(call);
+- list_del_init(&call->link);
+
+ pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n",
+ call, refcount_read(&call->ref),
+ rxrpc_call_states[call->state],
+ call->flags, call->events);
+
+- spin_unlock_bh(&rxnet->call_lock);
+- cond_resched();
+- spin_lock_bh(&rxnet->call_lock);
++ if (++shown >= 10)
++ break;
+ }
+
+ spin_unlock_bh(&rxnet->call_lock);
--- /dev/null
+From stable+bounces-237683-greg=kroah.com@vger.kernel.org Tue Apr 14 02:17:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 20:17:39 -0400
+Subject: rxrpc: Fix key quota calculation for multitoken keys
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414001739.3796841-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit bdbfead6d38979475df0c2f4bad2b19394fe9bdc ]
+
+In the rxrpc key preparsing, every token extracted sets the proposed quota
+value, but for multitoken keys, this will overwrite the previous proposed
+quota, losing it.
+
+Fix this by adding to the proposed quota instead.
+
+Fixes: 8a7a3eb4ddbe ("KEYS: RxRPC: Use key preparsing")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ dropped hunk for rxrpc_preparse_xdr_yfs_rxgk() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/key.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -72,7 +72,7 @@ static int rxrpc_preparse_xdr_rxkad(stru
+ return -EKEYREJECTED;
+
+ plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
+- prep->quotalen = datalen + plen;
++ prep->quotalen += datalen + plen;
+
+ plen -= sizeof(*token);
+ token = kzalloc(sizeof(*token), GFP_KERNEL);
+@@ -303,6 +303,7 @@ static int rxrpc_preparse(struct key_pre
+ memcpy(&kver, prep->data, sizeof(kver));
+ prep->data += sizeof(kver);
+ prep->datalen -= sizeof(kver);
++ prep->quotalen = 0;
+
+ _debug("KEY I/F VERSION: %u", kver);
+
+@@ -340,7 +341,7 @@ static int rxrpc_preparse(struct key_pre
+ goto error;
+
+ plen = sizeof(*token->kad) + v1->ticket_length;
+- prep->quotalen = plen + sizeof(*token);
++ prep->quotalen += plen + sizeof(*token);
+
+ ret = -ENOMEM;
+ token = kzalloc(sizeof(*token), GFP_KERNEL);
--- /dev/null
+From stable+bounces-237840-greg=kroah.com@vger.kernel.org Tue Apr 14 14:04:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Apr 2026 07:56:10 -0400
+Subject: rxrpc: reject undecryptable rxkad response tickets
+To: stable@vger.kernel.org
+Cc: Yuqi Xu <xuyuqiabc@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Yuan Tan <yuantan098@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Ren Wei <enjou1224z@gmail.com>, Ren Wei <n05ec@lzu.edu.cn>, David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414115610.548230-1-sashal@kernel.org>
+
+From: Yuqi Xu <xuyuqiabc@gmail.com>
+
+[ Upstream commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 ]
+
+rxkad_decrypt_ticket() decrypts the RXKAD response ticket and then
+parses the buffer as plaintext without checking whether
+crypto_skcipher_decrypt() succeeded.
+
+A malformed RESPONSE can therefore use a non-block-aligned ticket
+length, make the decrypt operation fail, and still drive the ticket
+parser with attacker-controlled bytes.
+
+Check the decrypt result and abort the connection with RXKADBADTICKET
+when ticket decryption fails.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Co-developed-by: Yuan Tan <yuantan098@gmail.com>
+Signed-off-by: Yuan Tan <yuantan098@gmail.com>
+Suggested-by: Xin Liu <bird@lzu.edu.cn>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-12-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted `rxrpc_abort_conn()` call to existing `goto other_error` error-handling pattern ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxkad.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -1013,8 +1013,13 @@ static int rxkad_decrypt_ticket(struct r
+ sg_init_one(&sg[0], ticket, ticket_len);
+ skcipher_request_set_callback(req, 0, NULL, NULL);
+ skcipher_request_set_crypt(req, sg, sg, ticket_len, iv.x);
+- crypto_skcipher_decrypt(req);
++ ret = crypto_skcipher_decrypt(req);
+ skcipher_request_free(req);
++ if (ret < 0) {
++ abort_code = RXKADBADTICKET;
++ ret = -EPROTO;
++ goto other_error;
++ }
+
+ p = ticket;
+ end = p + ticket_len;
gfs2-validate-i_depth-for-exhash-directories.patch
wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch
+netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch
+powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch
+arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
+arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch
+revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
+arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch
+ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch
+ocfs2-validate-inline-data-i_size-during-inode-read.patch
+ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch
+xfrm-clear-trailing-padding-in-build_polexpire.patch
+rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch
+rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
+rxrpc-reject-undecryptable-rxkad-response-tickets.patch
+fs-ocfs2-fix-comments-mentioning-i_mutex.patch
+ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch
+mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch
+mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch
+xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch
+tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch
+netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch
--- /dev/null
+From stable+bounces-230427-greg=kroah.com@vger.kernel.org Thu Mar 26 07:52:10 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Thu, 26 Mar 2026 14:51:39 +0800
+Subject: tty: n_gsm: fix deadlock and link starvation in outgoing data path
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Daniel Starke <daniel.starke@siemens.com>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260326065139.1735715-1-johnny_haocn@sina.com>
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 0af021678d5d30c31f5a6b631f404ead3575212a ]
+
+The current implementation queues up new control and user packets as needed
+and processes this queue down to the ldisc in the same code path.
+That means that the upper and the lower layer are hard coupled in the code.
+Due to this deadlocks can happen as seen below while transmitting data,
+especially during ldisc congestion. Furthermore, the data channels starve
+the control channel on high transmission load on the ldisc.
+
+Introduce an additional control channel data queue to prevent timeouts and
+link hangups during ldisc congestion. This is being processed before the
+user channel data queue in gsm_data_kick(), i.e. with the highest priority.
+Put the queue to ldisc data path into a workqueue and trigger it whenever
+new data has been put into the transmission queue. Change
+gsm_dlci_data_sweep() accordingly to fill up the transmission queue until
+TX_THRESH_HI. This solves the locking issue, keeps latency low and provides
+good performance on high data load.
+Note that now all packets from a DLCI are removed from the internal queue
+if the associated DLCI was closed. This ensures that no data is sent by the
+introduced write task to an already closed DLCI.
+
+BUG: spinlock recursion on CPU#0, test_v24_loop/124
+ lock: serial8250_ports+0x3a8/0x7500, .magic: dead4ead, .owner: test_v24_loop/124, .owner_cpu: 0
+CPU: 0 PID: 124 Comm: test_v24_loop Tainted: G O 5.18.0-rc2 #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Call Trace:
+ <IRQ>
+ dump_stack_lvl+0x34/0x44
+ do_raw_spin_lock+0x76/0xa0
+ _raw_spin_lock_irqsave+0x72/0x80
+ uart_write_room+0x3b/0xc0
+ gsm_data_kick+0x14b/0x240 [n_gsm]
+ gsmld_write_wakeup+0x35/0x70 [n_gsm]
+ tty_wakeup+0x53/0x60
+ tty_port_default_wakeup+0x1b/0x30
+ serial8250_tx_chars+0x12f/0x220
+ serial8250_handle_irq.part.0+0xfe/0x150
+ serial8250_default_handle_irq+0x48/0x80
+ serial8250_interrupt+0x56/0xa0
+ __handle_irq_event_percpu+0x78/0x1f0
+ handle_irq_event+0x34/0x70
+ handle_fasteoi_irq+0x90/0x1e0
+ __common_interrupt+0x69/0x100
+ common_interrupt+0x48/0xc0
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:__do_softirq+0x83/0x34e
+Code: 2a 0a ff 0f b7 ed c7 44 24 10 0a 00 00 00 48 c7 c7 51 2a 64 82 e8 2d
+e2 d5 ff 65 66 c7 05 83 af 1e 7e 00 00 fb b8 ff ff ff ff <49> c7 c2 40 61
+80 82 0f bc c5 41 89 c4 41 83 c4 01 0f 84 e6 00 00
+RSP: 0018:ffffc90000003f98 EFLAGS: 00000286
+RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: ffffffff82642a51 RDI: ffffffff825bb5e7
+RBP: 0000000000000200 R08: 00000008de3271a8 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000030 R14: 0000000000000000 R15: 0000000000000000
+ ? __do_softirq+0x73/0x34e
+ irq_exit_rcu+0xb5/0x100
+ common_interrupt+0xa4/0xc0
+ </IRQ>
+ <TASK>
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:_raw_spin_unlock_irqrestore+0x2e/0x50
+Code: 00 55 48 89 fd 48 83 c7 18 53 48 89 f3 48 8b 74 24 10 e8 85 28 36 ff
+48 89 ef e8 cd 58 36 ff 80 e7 02 74 01 fb bf 01 00 00 00 <e8> 3d 97 33 ff
+65 8b 05 96 23 2b 7e 85 c0 74 03 5b 5d c3 0f 1f 44
+RSP: 0018:ffffc9000020fd08 EFLAGS: 00000202
+RAX: 0000000000000000 RBX: 0000000000000246 RCX: 0000000000000000
+RDX: 0000000000000004 RSI: ffffffff8257fd74 RDI: 0000000000000001
+RBP: ffff8880057de3a0 R08: 00000008de233000 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000100 R14: 0000000000000202 R15: ffff8880057df0b8
+ ? _raw_spin_unlock_irqrestore+0x23/0x50
+ gsmtty_write+0x65/0x80 [n_gsm]
+ n_tty_write+0x33f/0x530
+ ? swake_up_all+0xe0/0xe0
+ file_tty_write.constprop.0+0x1b1/0x320
+ ? n_tty_flush_buffer+0xb0/0xb0
+ new_sync_write+0x10c/0x190
+ vfs_write+0x282/0x310
+ ksys_write+0x68/0xe0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x7f3e5e35c15c
+Code: 8b 7c 24 08 89 c5 e8 c5 ff ff ff 89 ef 89 44 24 08 e8 58 bc 02 00 8b
+44 24 08 48 83 c4 10 5d c3 48 63 ff b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff
+ff 76 10 48 8b 15 fd fc 05 00 f7 d8 64 89 02 48 83
+RSP: 002b:00007ffcee77cd18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 00007ffcee77cd70 RCX: 00007f3e5e35c15c
+RDX: 0000000000000100 RSI: 00007ffcee77cd90 RDI: 0000000000000003
+RBP: 0000000000000100 R08: 0000000000000000 R09: 7efefefefefefeff
+R10: 00007f3e5e3bddeb R11: 0000000000000246 R12: 00007ffcee77ce8f
+R13: 0000000000000001 R14: 000056214404e010 R15: 00007ffcee77cd90
+ </TASK>
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701122332.2039-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ The context change is due to the commit a8c5b8255f8a
+("tty: n_gsm: fix broken virtual tty handling") in v5.18
+which is irrelevant to the logic of this patch. ]
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c | 403 ++++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 279 insertions(+), 124 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -5,6 +5,14 @@
+ *
+ * * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE *
+ *
++ * Outgoing path:
++ * tty -> DLCI fifo -> scheduler -> GSM MUX data queue ---o-> ldisc
++ * control message -> GSM MUX control queue --´
++ *
++ * Incoming path:
++ * ldisc -> gsm_queue() -o--> tty
++ * `-> gsm_control_response()
++ *
+ * TO DO:
+ * Mostly done: ioctls for setting modes/timing
+ * Partly done: hooks so you can pull off frames to non tty devs
+@@ -212,6 +220,9 @@ struct gsm_mux {
+ /* Events on the GSM channel */
+ wait_queue_head_t event;
+
++ /* ldisc send work */
++ struct work_struct tx_work;
++
+ /* Bits for GSM mode decoding */
+
+ /* Framing Layer */
+@@ -243,7 +254,8 @@ struct gsm_mux {
+ unsigned int tx_bytes; /* TX data outstanding */
+ #define TX_THRESH_HI 8192
+ #define TX_THRESH_LO 2048
+- struct list_head tx_list; /* Pending data packets */
++ struct list_head tx_ctrl_list; /* Pending control packets */
++ struct list_head tx_data_list; /* Pending data packets */
+
+ /* Control messages */
+ struct timer_list kick_timer; /* Kick TX queuing on timeout */
+@@ -377,6 +389,11 @@ static const u8 gsm_fcs8[256] = {
+
+ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
+ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
++static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
++ u8 ctrl);
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
++static void gsmld_write_trigger(struct gsm_mux *gsm);
++static void gsmld_write_task(struct work_struct *work);
+
+ /**
+ * gsm_fcs_add - update FCS
+@@ -661,53 +678,73 @@ static int gsm_stuff_frame(const u8 *inp
+ * @cr: command/response bit seen as initiator
+ * @control: control byte including PF bit
+ *
+- * Format up and transmit a control frame. These do not go via the
+- * queueing logic as they should be transmitted ahead of data when
+- * they are needed.
+- *
+- * FIXME: Lock versus data TX path
++ * Format up and transmit a control frame. These should be transmitted
++ * ahead of data when they are needed.
+ */
+-
+-static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
++static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ {
+- int len;
+- u8 cbuf[10];
+- u8 ibuf[3];
++ struct gsm_msg *msg;
++ u8 *dp;
+ int ocr;
++ unsigned long flags;
++
++ msg = gsm_data_alloc(gsm, addr, 0, control);
++ if (!msg)
++ return -ENOMEM;
+
+ /* toggle C/R coding if not initiator */
+ ocr = cr ^ (gsm->initiator ? 0 : 1);
+
+- switch (gsm->encoding) {
+- case 0:
+- cbuf[0] = GSM0_SOF;
+- cbuf[1] = (addr << 2) | (ocr << 1) | EA;
+- cbuf[2] = control;
+- cbuf[3] = EA; /* Length of data = 0 */
+- cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
+- cbuf[5] = GSM0_SOF;
+- len = 6;
+- break;
+- case 1:
+- case 2:
+- /* Control frame + packing (but not frame stuffing) in mode 1 */
+- ibuf[0] = (addr << 2) | (ocr << 1) | EA;
+- ibuf[1] = control;
+- ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
+- /* Stuffing may double the size worst case */
+- len = gsm_stuff_frame(ibuf, cbuf + 1, 3);
+- /* Now add the SOF markers */
+- cbuf[0] = GSM1_SOF;
+- cbuf[len + 1] = GSM1_SOF;
+- /* FIXME: we can omit the lead one in many cases */
+- len += 2;
+- break;
+- default:
+- WARN_ON(1);
+- return;
++ msg->data -= 3;
++ dp = msg->data;
++ *dp++ = (addr << 2) | (ocr << 1) | EA;
++ *dp++ = control;
++
++ if (gsm->encoding == 0)
++ *dp++ = EA; /* Length of data = 0 */
++
++ *dp = 0xFF - gsm_fcs_add_block(INIT_FCS, msg->data, dp - msg->data);
++ msg->len = (dp - msg->data) + 1;
++
++ gsm_print_packet("Q->", addr, cr, control, NULL, 0);
++
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++ gsm->tx_bytes += msg->len;
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
++
++ return 0;
++}
++
++/**
++ * gsm_dlci_clear_queues - remove outstanding data for a DLCI
++ * @gsm: mux
++ * @dlci: clear for this DLCI
++ *
++ * Clears the data queues for a given DLCI.
++ */
++static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++{
++ struct gsm_msg *msg, *nmsg;
++ int addr = dlci->addr;
++ unsigned long flags;
++
++ /* Clear DLCI write fifo first */
++ spin_lock_irqsave(&dlci->lock, flags);
++ kfifo_reset(&dlci->fifo);
++ spin_unlock_irqrestore(&dlci->lock, flags);
++
++ /* Clear data packets in MUX write queue */
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++ if (msg->addr != addr)
++ continue;
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
+ }
+- gsmld_output(gsm, cbuf, len);
+- gsm_print_packet("-->", addr, cr, control, NULL, 0);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+
+ /**
+@@ -770,6 +807,45 @@ static struct gsm_msg *gsm_data_alloc(st
+ }
+
+ /**
++ * gsm_send_packet - sends a single packet
++ * @gsm: GSM Mux
++ * @msg: packet to send
++ *
++ * The given packet is encoded and sent out. No memory is freed.
++ * The caller must hold the gsm tx lock.
++ */
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg)
++{
++ int len, ret;
++
++
++ if (gsm->encoding == 0) {
++ gsm->txframe[0] = GSM0_SOF;
++ memcpy(gsm->txframe + 1, msg->data, msg->len);
++ gsm->txframe[msg->len + 1] = GSM0_SOF;
++ len = msg->len + 2;
++ } else {
++ gsm->txframe[0] = GSM1_SOF;
++ len = gsm_stuff_frame(msg->data, gsm->txframe + 1, msg->len);
++ gsm->txframe[len + 1] = GSM1_SOF;
++ len += 2;
++ }
++
++ if (debug & 4)
++ gsm_hex_dump_bytes(__func__, gsm->txframe, len);
++ gsm_print_packet("-->", msg->addr, gsm->initiator, msg->ctrl, msg->data,
++ msg->len);
++
++ ret = gsmld_output(gsm, gsm->txframe, len);
++ if (ret <= 0)
++ return ret;
++ /* FIXME: Can eliminate one SOF in many more cases */
++ gsm->tx_bytes -= msg->len;
++
++ return 0;
++}
++
++/**
+ * gsm_is_flow_ctrl_msg - checks if flow control message
+ * @msg: message to check
+ *
+@@ -801,59 +877,81 @@ static bool gsm_is_flow_ctrl_msg(struct
+ }
+
+ /**
+- * gsm_data_kick - poke the queue
++ * gsm_data_kick - poke the queue
+ * @gsm: GSM Mux
+- * @dlci: DLCI sending the data
+ *
+ * The tty device has called us to indicate that room has appeared in
+- * the transmit queue. Ram more data into the pipe if we have any
++ * the transmit queue. Ram more data into the pipe if we have any.
+ * If we have been flow-stopped by a CMD_FCOFF, then we can only
+- * send messages on DLCI0 until CMD_FCON
+- *
+- * FIXME: lock against link layer control transmissions
++ * send messages on DLCI0 until CMD_FCON. The caller must hold
++ * the gsm tx lock.
+ */
+-
+-static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++static int gsm_data_kick(struct gsm_mux *gsm)
+ {
+ struct gsm_msg *msg, *nmsg;
+- int len;
++ struct gsm_dlci *dlci;
++ int ret;
+
+- list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
++ clear_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
++
++ /* Serialize control messages and control channel messages first */
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) {
+ if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
++ return -EAGAIN;
++ ret = gsm_send_packet(gsm, msg);
++ switch (ret) {
++ case -ENOSPC:
++ return -ENOSPC;
++ case -ENODEV:
++ /* ldisc not open */
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
+ continue;
+- if (gsm->encoding != 0) {
+- gsm->txframe[0] = GSM1_SOF;
+- len = gsm_stuff_frame(msg->data,
+- gsm->txframe + 1, msg->len);
+- gsm->txframe[len + 1] = GSM1_SOF;
+- len += 2;
+- } else {
+- gsm->txframe[0] = GSM0_SOF;
+- memcpy(gsm->txframe + 1 , msg->data, msg->len);
+- gsm->txframe[msg->len + 1] = GSM0_SOF;
+- len = msg->len + 2;
+- }
+-
+- if (debug & 4)
+- gsm_hex_dump_bytes(__func__, gsm->txframe, len);
+- if (gsmld_output(gsm, gsm->txframe, len) <= 0)
++ default:
++ if (ret >= 0) {
++ list_del(&msg->list);
++ kfree(msg);
++ }
+ break;
+- /* FIXME: Can eliminate one SOF in many more cases */
+- gsm->tx_bytes -= msg->len;
+-
+- list_del(&msg->list);
+- kfree(msg);
++ }
++ }
+
+- if (dlci) {
+- tty_port_tty_wakeup(&dlci->port);
+- } else {
+- int i = 0;
++ if (gsm->constipated)
++ return -EAGAIN;
+
+- for (i = 0; i < NUM_DLCI; i++)
+- if (gsm->dlci[i])
+- tty_port_tty_wakeup(&gsm->dlci[i]->port);
++ /* Serialize other channels */
++ if (list_empty(&gsm->tx_data_list))
++ return 0;
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++ dlci = gsm->dlci[msg->addr];
++ /* Send only messages for DLCIs with valid state */
++ if (dlci->state != DLCI_OPEN) {
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
++ continue;
++ }
++ ret = gsm_send_packet(gsm, msg);
++ switch (ret) {
++ case -ENOSPC:
++ return -ENOSPC;
++ case -ENODEV:
++ /* ldisc not open */
++ gsm->tx_bytes -= msg->len;
++ list_del(&msg->list);
++ kfree(msg);
++ continue;
++ default:
++ if (ret >= 0) {
++ list_del(&msg->list);
++ kfree(msg);
++ }
++ break;
+ }
+ }
++
++ return 1;
+ }
+
+ /**
+@@ -902,9 +1000,21 @@ static void __gsm_data_queue(struct gsm_
+ msg->data = dp;
+
+ /* Add to the actual output queue */
+- list_add_tail(&msg->list, &gsm->tx_list);
++ switch (msg->ctrl & ~PF) {
++ case UI:
++ case UIH:
++ if (msg->addr > 0) {
++ list_add_tail(&msg->list, &gsm->tx_data_list);
++ break;
++ }
++ fallthrough;
++ default:
++ list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++ break;
++ }
+ gsm->tx_bytes += msg->len;
+- gsm_data_kick(gsm, dlci);
++
++ gsmld_write_trigger(gsm);
+ mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+
+@@ -1131,32 +1241,39 @@ static int gsm_dlci_modem_output(struct
+
+ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ {
+- int len, ret = 0;
+ /* Priority ordering: We should do priority with RR of the groups */
+- int i = 1;
+-
+- while (i < NUM_DLCI) {
+- struct gsm_dlci *dlci;
++ int i, len, ret = 0;
++ bool sent;
++ struct gsm_dlci *dlci;
+
+- if (gsm->tx_bytes > TX_THRESH_HI)
+- break;
+- dlci = gsm->dlci[i];
+- if (dlci == NULL || dlci->constipated) {
+- i++;
+- continue;
++ while (gsm->tx_bytes < TX_THRESH_HI) {
++ for (sent = false, i = 1; i < NUM_DLCI; i++) {
++ dlci = gsm->dlci[i];
++ /* skip unused or blocked channel */
++ if (!dlci || dlci->constipated)
++ continue;
++ /* skip channels with invalid state */
++ if (dlci->state != DLCI_OPEN)
++ continue;
++ /* count the sent data per adaption */
++ if (dlci->adaption < 3 && !dlci->net)
++ len = gsm_dlci_data_output(gsm, dlci);
++ else
++ len = gsm_dlci_data_output_framed(gsm, dlci);
++ /* on error exit */
++ if (len < 0)
++ return ret;
++ if (len > 0) {
++ ret++;
++ sent = true;
++ /* The lower DLCs can starve the higher DLCs! */
++ break;
++ }
++ /* try next */
+ }
+- if (dlci->adaption < 3 && !dlci->net)
+- len = gsm_dlci_data_output(gsm, dlci);
+- else
+- len = gsm_dlci_data_output_framed(gsm, dlci);
+- if (len < 0)
++ if (!sent)
+ break;
+- /* DLCI empty - try the next */
+- if (len == 0)
+- i++;
+- else
+- ret++;
+- }
++ };
+
+ return ret;
+ }
+@@ -1405,7 +1522,6 @@ static void gsm_control_message(struct g
+ const u8 *data, int clen)
+ {
+ u8 buf[1];
+- unsigned long flags;
+ struct gsm_dlci *dlci;
+ int i;
+ int address;
+@@ -1440,9 +1556,7 @@ static void gsm_control_message(struct g
+ gsm->constipated = false;
+ gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+ /* Kick the link in case it is idling */
+- spin_lock_irqsave(&gsm->tx_lock, flags);
+- gsm_data_kick(gsm, NULL);
+- spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
+ break;
+ case CMD_FCOFF:
+ /* Modem wants us to STFU */
+@@ -1645,8 +1759,6 @@ static int gsm_control_wait(struct gsm_m
+
+ static void gsm_dlci_close(struct gsm_dlci *dlci)
+ {
+- unsigned long flags;
+-
+ del_timer(&dlci->t1);
+ if (debug & 8)
+ pr_debug("DLCI %d goes closed.\n", dlci->addr);
+@@ -1655,17 +1767,16 @@ static void gsm_dlci_close(struct gsm_dl
+ dlci->constipated = true;
+ if (dlci->addr != 0) {
+ tty_port_tty_hangup(&dlci->port, false);
+- spin_lock_irqsave(&dlci->lock, flags);
+- kfifo_reset(&dlci->fifo);
+- spin_unlock_irqrestore(&dlci->lock, flags);
++ gsm_dlci_clear_queues(dlci->gsm, dlci);
+ /* Ensure that gsmtty_open() can return. */
+ tty_port_set_initialized(&dlci->port, 0);
+ wake_up_interruptible(&dlci->port.open_wait);
+ } else
+ dlci->gsm->dead = true;
+- wake_up(&dlci->gsm->event);
+ /* A DLCI 0 close is a MUX termination so we need to kick that
+ back to userspace somehow */
++ gsm_dlci_data_kick(dlci);
++ wake_up(&dlci->gsm->event);
+ }
+
+ /**
+@@ -1688,6 +1799,7 @@ static void gsm_dlci_open(struct gsm_dlc
+ /* Send current modem state */
+ if (dlci->addr)
+ gsm_modem_update(dlci, 0);
++ gsm_dlci_data_kick(dlci);
+ wake_up(&dlci->gsm->event);
+ }
+
+@@ -2325,7 +2437,7 @@ static void gsm1_receive(struct gsm_mux
+ } else if ((c & ISO_IEC_646_MASK) == XOFF) {
+ gsm->constipated = false;
+ /* Kick the link in case it is idling */
+- gsm_data_kick(gsm, NULL);
++ gsmld_write_trigger(gsm);
+ return;
+ }
+ if (c == GSM1_SOF) {
+@@ -2460,6 +2572,9 @@ static void gsm_cleanup_mux(struct gsm_m
+ del_timer_sync(&gsm->kick_timer);
+ del_timer_sync(&gsm->t2_timer);
+
++ /* Finish writing to ldisc */
++ flush_work(&gsm->tx_work);
++
+ /* Free up any link layer users and finally the control channel */
+ if (gsm->has_devices) {
+ gsm_unregister_devices(gsm_tty_driver, gsm->num);
+@@ -2471,9 +2586,12 @@ static void gsm_cleanup_mux(struct gsm_m
+ mutex_unlock(&gsm->mutex);
+ /* Now wipe the queues */
+ tty_ldisc_flush(gsm->tty);
+- list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
++ list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list)
++ kfree(txq);
++ INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++ list_for_each_entry_safe(txq, ntxq, &gsm->tx_data_list, list)
+ kfree(txq);
+- INIT_LIST_HEAD(&gsm->tx_list);
++ INIT_LIST_HEAD(&gsm->tx_data_list);
+ }
+
+ /**
+@@ -2496,6 +2614,7 @@ static int gsm_activate_mux(struct gsm_m
+
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+ init_waitqueue_head(&gsm->event);
+ spin_lock_init(&gsm->control_lock);
+ spin_lock_init(&gsm->tx_lock);
+@@ -2602,7 +2721,8 @@ static struct gsm_mux *gsm_alloc_mux(voi
+ spin_lock_init(&gsm->lock);
+ mutex_init(&gsm->mutex);
+ kref_init(&gsm->ref);
+- INIT_LIST_HEAD(&gsm->tx_list);
++ INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++ INIT_LIST_HEAD(&gsm->tx_data_list);
+
+ gsm->t1 = T1;
+ gsm->t2 = T2;
+@@ -2759,6 +2879,47 @@ static int gsmld_output(struct gsm_mux *
+ return gsm->tty->ops->write(gsm->tty, data, len);
+ }
+
++
++/**
++ * gsmld_write_trigger - schedule ldisc write task
++ * @gsm: our mux
++ */
++static void gsmld_write_trigger(struct gsm_mux *gsm)
++{
++ if (!gsm || !gsm->dlci[0] || gsm->dlci[0]->dead)
++ return;
++ schedule_work(&gsm->tx_work);
++}
++
++
++/**
++ * gsmld_write_task - ldisc write task
++ * @work: our tx write work
++ *
++ * Writes out data to the ldisc if possible. We are doing this here to
++ * avoid dead-locking. This returns if no space or data is left for output.
++ */
++static void gsmld_write_task(struct work_struct *work)
++{
++ struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++ unsigned long flags;
++ int i, ret;
++
++ /* All outstanding control channel and control messages and one data
++ * frame is sent.
++ */
++ ret = -ENODEV;
++ spin_lock_irqsave(&gsm->tx_lock, flags);
++ if (gsm->tty)
++ ret = gsm_data_kick(gsm);
++ spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++ if (ret >= 0)
++ for (i = 0; i < NUM_DLCI; i++)
++ if (gsm->dlci[i])
++ tty_port_tty_wakeup(&gsm->dlci[i]->port);
++}
++
+ /**
+ * gsmld_attach_gsm - mode set up
+ * @tty: our tty structure
+@@ -2902,6 +3063,7 @@ static int gsmld_open(struct tty_struct
+
+ timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++ INIT_WORK(&gsm->tx_work, gsmld_write_task);
+
+ return 0;
+ }
+@@ -2918,16 +3080,9 @@ static int gsmld_open(struct tty_struct
+ static void gsmld_write_wakeup(struct tty_struct *tty)
+ {
+ struct gsm_mux *gsm = tty->disc_data;
+- unsigned long flags;
+
+ /* Queue poll */
+- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+- spin_lock_irqsave(&gsm->tx_lock, flags);
+- gsm_data_kick(gsm, NULL);
+- if (gsm->tx_bytes < TX_THRESH_LO) {
+- gsm_dlci_data_sweep(gsm);
+- }
+- spin_unlock_irqrestore(&gsm->tx_lock, flags);
++ gsmld_write_trigger(gsm);
+ }
+
+ /**
--- /dev/null
+From johnny_haocn@sina.com Fri Mar 27 06:59:57 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Fri, 27 Mar 2026 13:59:50 +0800
+Subject: xen-netfront: handle NULL returned by xdp_convert_buff_to_frame()
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Alexey Nepomnyashih <sdl@nppct.ru>, Jakub Kicinski <kuba@kernel.org>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260327055950.2618928-1-johnny_haocn@sina.com>
+
+From: Alexey Nepomnyashih <sdl@nppct.ru>
+
+[ Upstream commit cc3628dcd851ddd8d418bf0c897024b4621ddc92 ]
+
+The function xdp_convert_buff_to_frame() may return NULL if it fails
+to correctly convert the XDP buffer into an XDP frame due to memory
+constraints, internal errors, or invalid data. Failing to check for NULL
+may lead to a NULL pointer dereference if the result is used later in
+processing, potentially causing crashes, data corruption, or undefined
+behavior.
+
+On XDP redirect failure, the associated page must be released explicitly
+if it was previously retained via get_page(). Failing to do so may result
+in a memory leak, as the pages reference count is not decremented.
+
+Cc: stable@vger.kernel.org # v5.9+
+Fixes: 6c5aa6fc4def ("xen networking: add basic XDP support for xen-netfront")
+Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
+Link: https://patch.msgid.link/20250417122118.1009824-1-sdl@nppct.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netfront.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -982,20 +982,27 @@ static u32 xennet_run_xdp(struct netfron
+ act = bpf_prog_run_xdp(prog, xdp);
+ switch (act) {
+ case XDP_TX:
+- get_page(pdata);
+ xdpf = xdp_convert_buff_to_frame(xdp);
++ if (unlikely(!xdpf)) {
++ trace_xdp_exception(queue->info->netdev, prog, act);
++ break;
++ }
++ get_page(pdata);
+ err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
+- if (unlikely(!err))
++ if (unlikely(err <= 0)) {
++ if (err < 0)
++ trace_xdp_exception(queue->info->netdev, prog, act);
+ xdp_return_frame_rx_napi(xdpf);
+- else if (unlikely(err < 0))
+- trace_xdp_exception(queue->info->netdev, prog, act);
++ }
+ break;
+ case XDP_REDIRECT:
+ get_page(pdata);
+ err = xdp_do_redirect(queue->info->netdev, xdp, prog);
+ *need_xdp_flush = true;
+- if (unlikely(err))
++ if (unlikely(err)) {
+ trace_xdp_exception(queue->info->netdev, prog, act);
++ xdp_return_buff(xdp);
++ }
+ break;
+ case XDP_PASS:
+ case XDP_DROP:
--- /dev/null
+From stable+bounces-237666-greg=kroah.com@vger.kernel.org Mon Apr 13 23:59:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 17:59:48 -0400
+Subject: xfrm: clear trailing padding in build_polexpire()
+To: stable@vger.kernel.org
+Cc: Yasuaki Torimaru <yasuakitorimaru@gmail.com>, Simon Horman <horms@kernel.org>, Breno Leitao <leitao@debian.org>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413215948.3711943-1-sashal@kernel.org>
+
+From: Yasuaki Torimaru <yasuakitorimaru@gmail.com>
+
+[ Upstream commit 71a98248c63c535eaa4d4c22f099b68d902006d0 ]
+
+build_expire() clears the trailing padding bytes of struct
+xfrm_user_expire after setting the hard field via memset_after(),
+but the analogous function build_polexpire() does not do this for
+struct xfrm_user_polexpire.
+
+The padding bytes after the __u8 hard field are left
+uninitialized from the heap allocation, and are then sent to
+userspace via netlink multicast to XFRMNLGRP_EXPIRE listeners,
+leaking kernel heap memory contents.
+
+Add the missing memset_after() call, matching build_expire().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Yasuaki Torimaru <yasuakitorimaru@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+[ replaced `memset_after()` macro with equivalent manual `memset()` call ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_user.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -3389,6 +3389,8 @@ static int build_polexpire(struct sk_buf
+ return err;
+ }
+ upe->hard = !!hard;
++ /* clear the padding bytes */
++ memset(&upe->hard + 1, 0, sizeof(*upe) - offsetofend(typeof(*upe), hard));
+
+ nlmsg_end(skb, nlh);
+ return 0;