--- /dev/null
+From stable+bounces-114132-greg=kroah.com@vger.kernel.org Thu Feb 6 17:21:33 2025
+From: Koichiro Den <koichiro.den@canonical.com>
+Date: Fri, 7 Feb 2025 01:20:55 +0900
+Subject: btrfs: avoid monopolizing a core when activating a swap file
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: wqu@suse.com, fdmanana@suse.com, dsterba@suse.com
+Message-ID: <20250206162055.1387169-2-koichiro.den@canonical.com>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 2c8507c63f5498d4ee4af404a8e44ceae4345056 upstream.
+
+This commit re-attempts the backport of the change to the linux-6.1.y
+branch. Commit bb8e287f596b ("btrfs: avoid monopolizing a core when
+activating a swap file") on this branch was reverted.
+
+During swap activation we iterate over the extents of a file and we can
+have many thousands of them, so we can end up in a busy loop monopolizing
+a core. Avoid this by doing a voluntary reschedule after processing each
+extent.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -11368,6 +11368,8 @@ static int btrfs_swap_activate(struct sw
+ }
+
+ start += len;
++
++ cond_resched();
+ }
+
+ if (bsi.block_len)
--- /dev/null
+From 31ad74b20227ce6b40910ff78b1c604e42975cf1 Mon Sep 17 00:00:00 2001
+From: Zizhi Wo <wozizhi@huawei.com>
+Date: Thu, 7 Nov 2024 19:06:48 +0800
+Subject: cachefiles: Fix NULL pointer dereference in object->file
+
+From: Zizhi Wo <wozizhi@huawei.com>
+
+commit 31ad74b20227ce6b40910ff78b1c604e42975cf1 upstream.
+
+At present, the object->file has the NULL pointer dereference problem in
+ondemand-mode. The root cause is that the allocated fd and object->file
+lifetime are inconsistent, and the user-space invocation to anon_fd uses
+object->file. Following is the process that triggers the issue:
+
+ [write fd] [umount]
+cachefiles_ondemand_fd_write_iter
+ fscache_cookie_state_machine
+ cachefiles_withdraw_cookie
+ if (!file) return -ENOBUFS
+ cachefiles_clean_up_object
+ cachefiles_unmark_inode_in_use
+ fput(object->file)
+ object->file = NULL
+ // file NULL pointer dereference!
+ __cachefiles_write(..., file, ...)
+
+Fix this issue by add an additional reference count to the object->file
+before write/llseek, and decrement after it finished.
+
+Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
+Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
+Link: https://lore.kernel.org/r/20241107110649.3980193-5-wozizhi@huawei.com
+Reviewed-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Bin Lan <lanbincn@qq.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cachefiles/interface.c | 14 ++++++++++----
+ fs/cachefiles/ondemand.c | 30 ++++++++++++++++++++++++------
+ 2 files changed, 34 insertions(+), 10 deletions(-)
+
+--- a/fs/cachefiles/interface.c
++++ b/fs/cachefiles/interface.c
+@@ -327,6 +327,8 @@ static void cachefiles_commit_object(str
+ static void cachefiles_clean_up_object(struct cachefiles_object *object,
+ struct cachefiles_cache *cache)
+ {
++ struct file *file;
++
+ if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) {
+ if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
+ cachefiles_see_object(object, cachefiles_obj_see_clean_delete);
+@@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(s
+ }
+
+ cachefiles_unmark_inode_in_use(object, object->file);
+- if (object->file) {
+- fput(object->file);
+- object->file = NULL;
+- }
++
++ spin_lock(&object->lock);
++ file = object->file;
++ object->file = NULL;
++ spin_unlock(&object->lock);
++
++ if (file)
++ fput(file);
+ }
+
+ /*
+--- a/fs/cachefiles/ondemand.c
++++ b/fs/cachefiles/ondemand.c
+@@ -61,20 +61,26 @@ static ssize_t cachefiles_ondemand_fd_wr
+ {
+ struct cachefiles_object *object = kiocb->ki_filp->private_data;
+ struct cachefiles_cache *cache = object->volume->cache;
+- struct file *file = object->file;
++ struct file *file;
+ size_t len = iter->count;
+ loff_t pos = kiocb->ki_pos;
+ const struct cred *saved_cred;
+ int ret;
+
+- if (!file)
++ spin_lock(&object->lock);
++ file = object->file;
++ if (!file) {
++ spin_unlock(&object->lock);
+ return -ENOBUFS;
++ }
++ get_file(file);
++ spin_unlock(&object->lock);
+
+ cachefiles_begin_secure(cache, &saved_cred);
+ ret = __cachefiles_prepare_write(object, file, &pos, &len, true);
+ cachefiles_end_secure(cache, saved_cred);
+ if (ret < 0)
+- return ret;
++ goto out;
+
+ trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
+ ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
+@@ -83,6 +89,8 @@ static ssize_t cachefiles_ondemand_fd_wr
+ kiocb->ki_pos += ret;
+ }
+
++out:
++ fput(file);
+ return ret;
+ }
+
+@@ -90,12 +98,22 @@ static loff_t cachefiles_ondemand_fd_lls
+ int whence)
+ {
+ struct cachefiles_object *object = filp->private_data;
+- struct file *file = object->file;
++ struct file *file;
++ loff_t ret;
+
+- if (!file)
++ spin_lock(&object->lock);
++ file = object->file;
++ if (!file) {
++ spin_unlock(&object->lock);
+ return -ENOBUFS;
++ }
++ get_file(file);
++ spin_unlock(&object->lock);
+
+- return vfs_llseek(file, pos, whence);
++ ret = vfs_llseek(file, pos, whence);
++ fput(file);
++
++ return ret;
+ }
+
+ static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
+++ /dev/null
-From 60ef10ac7a15a6cfc0d7c5f9f5381d9893946e3c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 6 Dec 2024 11:43:12 +0200
-Subject: drm/sti: hdmi: use eld_mutex to protect access to connector->eld
-
-From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
-
-[ Upstream commit e99c0b517bcd53cf61f998a3c4291333401cb391 ]
-
-Reading access to connector->eld can happen at the same time the
-drm_edid_to_eld() updates the data. Take the newly added eld_mutex in
-order to protect connector->eld from concurrent access.
-
-Reviewed-by: Maxime Ripard <mripard@kernel.org>
-Acked-by: Raphael Gallais-Pou <rgallaispou@gmail.com>
-Link: https://patchwork.freedesktop.org/patch/msgid/20241206-drm-connector-eld-mutex-v2-9-c9bce1ee8bea@linaro.org
-Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/gpu/drm/sti/sti_hdmi.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
-index 8539fe1fedc4c..fdb28e05720ad 100644
---- a/drivers/gpu/drm/sti/sti_hdmi.c
-+++ b/drivers/gpu/drm/sti/sti_hdmi.c
-@@ -1220,7 +1220,9 @@ static int hdmi_audio_get_eld(struct device *dev, void *data, uint8_t *buf, size
- struct drm_connector *connector = hdmi->drm_connector;
-
- DRM_DEBUG_DRIVER("\n");
-+ mutex_lock(&connector->eld_mutex);
- memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-+ mutex_unlock(&connector->eld_mutex);
-
- return 0;
- }
---
-2.39.5
-
--- /dev/null
+From 985b67cd86392310d9e9326de941c22fc9340eec Mon Sep 17 00:00:00 2001
+From: Lizhi Xu <lizhi.xu@windriver.com>
+Date: Wed, 5 Jun 2024 09:23:35 +0800
+Subject: ext4: filesystems without casefold feature cannot be mounted with siphash
+
+From: Lizhi Xu <lizhi.xu@windriver.com>
+
+commit 985b67cd86392310d9e9326de941c22fc9340eec upstream.
+
+When mounting the ext4 filesystem, if the default hash version is set to
+DX_HASH_SIPHASH but the casefold feature is not set, exit the mounting.
+
+Reported-by: syzbot+340581ba9dceb7e06fb3@syzkaller.appspotmail.com
+Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
+Link: https://patch.msgid.link/20240605012335.44086-1-lizhi.xu@windriver.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Bruno VERNAY <bruno.vernay@se.com>
+Signed-off-by: Victor Giraud <vgiraud.opensource@witekio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3547,6 +3547,14 @@ int ext4_feature_set_ok(struct super_blo
+ }
+ #endif
+
++ if (EXT4_SB(sb)->s_es->s_def_hash_version == DX_HASH_SIPHASH &&
++ !ext4_has_feature_casefold(sb)) {
++ ext4_msg(sb, KERN_ERR,
++ "Filesystem without casefold feature cannot be "
++ "mounted with siphash");
++ return 0;
++ }
++
+ if (readonly)
+ return 1;
+
--- /dev/null
+From 5729e06c819184b7ba40869c1ad53e1a463040b2 Mon Sep 17 00:00:00 2001
+From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
+Date: Thu, 18 May 2023 10:55:10 -0400
+Subject: maple_tree: fix static analyser cppcheck issue
+
+From: Liam R. Howlett <Liam.Howlett@oracle.com>
+
+commit 5729e06c819184b7ba40869c1ad53e1a463040b2 upstream.
+
+Patch series "Maple tree mas_{next,prev}_range() and cleanup", v4.
+
+This patchset contains a number of clean ups to the code to make it more
+usable (next/prev range), the addition of debug output formatting, the
+addition of printing the maple state information in the WARN_ON/BUG_ON
+code.
+
+There is also work done here to keep nodes active during iterations to
+reduce the necessity of re-walking the tree.
+
+Finally, there is a new interface added to move to the next or previous
+range in the tree, even if it is empty.
+
+The organisation of the patches is as follows:
+
+0001-0004 - Small clean ups
+0005-0018 - Additional debug options and WARN_ON/BUG_ON changes
+0019 - Test module __init and __exit addition
+0020-0021 - More functional clean ups
+0022-0026 - Changes to keep nodes active
+0027-0034 - Add new mas_{prev,next}_range()
+0035 - Use new mas_{prev,next}_range() in mmap_region()
+
+
+This patch (of 35):
+
+Static analyser of the maple tree code noticed that the split variable is
+being used to dereference into an array prior to checking the variable
+itself. Fix this issue by changing the order of the statement to check
+the variable first.
+
+Link: https://lkml.kernel.org/r/20230518145544.1722059-1-Liam.Howlett@oracle.com
+Link: https://lkml.kernel.org/r/20230518145544.1722059-2-Liam.Howlett@oracle.com
+Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
+Reported-by: David Binderman <dcb314@hotmail.com>
+Reviewed-by: Peng Zhang<zhangpeng.00@bytedance.com>
+Cc: Sergey Senozhatsky <senozhatsky@chromium.org>
+Cc: Vernon Yang <vernon2gm@gmail.com>
+Cc: Wei Yang <richard.weiyang@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -1935,8 +1935,9 @@ static inline int mab_calc_split(struct
+ * causes one node to be deficient.
+ * NOTE: mt_min_slots is 1 based, b_end and split are zero.
+ */
+- while (((bn->pivot[split] - min) < slot_count - 1) &&
+- (split < slot_count - 1) && (b_end - split > slot_min))
++ while ((split < slot_count - 1) &&
++ ((bn->pivot[split] - min) < slot_count - 1) &&
++ (b_end - split > slot_min))
+ split++;
+ }
+
--- /dev/null
+From 4f6a6bed0bfef4b966f076f33eb4f5547226056a Mon Sep 17 00:00:00 2001
+From: Wei Yang <richard.weiyang@gmail.com>
+Date: Wed, 13 Nov 2024 03:16:14 +0000
+Subject: maple_tree: simplify split calculation
+
+From: Wei Yang <richard.weiyang@gmail.com>
+
+commit 4f6a6bed0bfef4b966f076f33eb4f5547226056a upstream.
+
+Patch series "simplify split calculation", v3.
+
+
+This patch (of 3):
+
+The current calculation for splitting nodes tries to enforce a minimum
+span on the leaf nodes. This code is complex and never worked correctly
+to begin with, due to the min value being passed as 0 for all leaves.
+
+The calculation should just split the data as equally as possible
+between the new nodes. Note that b_end will be one more than the data,
+so the left side is still favoured in the calculation.
+
+The current code may also lead to a deficient node by not leaving enough
+data for the right side of the split. This issue is also addressed with
+the split calculation change.
+
+[Liam.Howlett@Oracle.com: rephrase the change log]
+Link: https://lkml.kernel.org/r/20241113031616.10530-1-richard.weiyang@gmail.com
+Link: https://lkml.kernel.org/r/20241113031616.10530-2-richard.weiyang@gmail.com
+Fixes: 54a611b60590 ("Maple Tree: add new data structure")
+Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
+Reviewed-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ lib/maple_tree.c | 23 ++++++-----------------
+ 1 file changed, 6 insertions(+), 17 deletions(-)
+
+--- a/lib/maple_tree.c
++++ b/lib/maple_tree.c
+@@ -1890,11 +1890,11 @@ static inline int mab_no_null_split(stru
+ * Return: The first split location. The middle split is set in @mid_split.
+ */
+ static inline int mab_calc_split(struct ma_state *mas,
+- struct maple_big_node *bn, unsigned char *mid_split, unsigned long min)
++ struct maple_big_node *bn, unsigned char *mid_split)
+ {
+ unsigned char b_end = bn->b_end;
+ int split = b_end / 2; /* Assume equal split. */
+- unsigned char slot_min, slot_count = mt_slots[bn->type];
++ unsigned char slot_count = mt_slots[bn->type];
+
+ /*
+ * To support gap tracking, all NULL entries are kept together and a node cannot
+@@ -1927,18 +1927,7 @@ static inline int mab_calc_split(struct
+ split = b_end / 3;
+ *mid_split = split * 2;
+ } else {
+- slot_min = mt_min_slots[bn->type];
+-
+ *mid_split = 0;
+- /*
+- * Avoid having a range less than the slot count unless it
+- * causes one node to be deficient.
+- * NOTE: mt_min_slots is 1 based, b_end and split are zero.
+- */
+- while ((split < slot_count - 1) &&
+- ((bn->pivot[split] - min) < slot_count - 1) &&
+- (b_end - split > slot_min))
+- split++;
+ }
+
+ /* Avoid ending a node on a NULL entry */
+@@ -2664,7 +2653,7 @@ static inline struct maple_enode
+ static inline unsigned char mas_mab_to_node(struct ma_state *mas,
+ struct maple_big_node *b_node, struct maple_enode **left,
+ struct maple_enode **right, struct maple_enode **middle,
+- unsigned char *mid_split, unsigned long min)
++ unsigned char *mid_split)
+ {
+ unsigned char split = 0;
+ unsigned char slot_count = mt_slots[b_node->type];
+@@ -2677,7 +2666,7 @@ static inline unsigned char mas_mab_to_n
+ if (b_node->b_end < slot_count) {
+ split = b_node->b_end;
+ } else {
+- split = mab_calc_split(mas, b_node, mid_split, min);
++ split = mab_calc_split(mas, b_node, mid_split);
+ *right = mas_new_ma_node(mas, b_node);
+ }
+
+@@ -3076,7 +3065,7 @@ static int mas_spanning_rebalance(struct
+ mast->bn->b_end--;
+ mast->bn->type = mte_node_type(mast->orig_l->node);
+ split = mas_mab_to_node(mas, mast->bn, &left, &right, &middle,
+- &mid_split, mast->orig_l->min);
++ &mid_split);
+ mast_set_split_parents(mast, left, middle, right, split,
+ mid_split);
+ mast_cp_to_nodes(mast, left, middle, right, split, mid_split);
+@@ -3591,7 +3580,7 @@ static int mas_split(struct ma_state *ma
+ if (mas_push_data(mas, height, &mast, false))
+ break;
+
+- split = mab_calc_split(mas, b_node, &mid_split, prev_l_mas.min);
++ split = mab_calc_split(mas, b_node, &mid_split);
+ mast_split_data(&mast, mas, split);
+ /*
+ * Usually correct, mab_mas_cp in the above call overwrites
--- /dev/null
+From stable+bounces-114459-greg=kroah.com@vger.kernel.org Sun Feb 9 18:48:42 2025
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Sun, 9 Feb 2025 18:48:30 +0100
+Subject: mptcp: pm: only set fullmesh for subflow endp
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, syzbot+cd16e79c1e45f3fe0377@syzkaller.appspotmail.com, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20250209174828.3397229-5-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+commit 1bb0d1348546ad059f55c93def34e67cb2a034a6 upstream.
+
+With the in-kernel path-manager, it is possible to change the 'fullmesh'
+flag. The code in mptcp_pm_nl_fullmesh() expects to change it only on
+'subflow' endpoints, to recreate more or less subflows using the linked
+address.
+
+Unfortunately, the set_flags() hook was a bit more permissive, and
+allowed 'implicit' endpoints to get the 'fullmesh' flag while it is not
+allowed before.
+
+That's what syzbot found, triggering the following warning:
+
+ WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 __mark_subflow_endp_available net/mptcp/pm_netlink.c:1496 [inline]
+ WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_pm_nl_fullmesh net/mptcp/pm_netlink.c:1980 [inline]
+ WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_nl_set_flags net/mptcp/pm_netlink.c:2003 [inline]
+ WARNING: CPU: 0 PID: 6499 at net/mptcp/pm_netlink.c:1496 mptcp_pm_nl_set_flags+0x974/0xdc0 net/mptcp/pm_netlink.c:2064
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 6499 Comm: syz.1.413 Not tainted 6.13.0-rc5-syzkaller-00172-gd1bf27c4e176 #0
+ Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
+ RIP: 0010:__mark_subflow_endp_available net/mptcp/pm_netlink.c:1496 [inline]
+ RIP: 0010:mptcp_pm_nl_fullmesh net/mptcp/pm_netlink.c:1980 [inline]
+ RIP: 0010:mptcp_nl_set_flags net/mptcp/pm_netlink.c:2003 [inline]
+ RIP: 0010:mptcp_pm_nl_set_flags+0x974/0xdc0 net/mptcp/pm_netlink.c:2064
+ Code: 01 00 00 49 89 c5 e8 fb 45 e8 f5 e9 b8 fc ff ff e8 f1 45 e8 f5 4c 89 f7 be 03 00 00 00 e8 44 1d 0b f9 eb a0 e8 dd 45 e8 f5 90 <0f> 0b 90 e9 17 ff ff ff 89 d9 80 e1 07 38 c1 0f 8c c9 fc ff ff 48
+ RSP: 0018:ffffc9000d307240 EFLAGS: 00010293
+ RAX: ffffffff8bb72e03 RBX: 0000000000000000 RCX: ffff88807da88000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: ffffc9000d307430 R08: ffffffff8bb72cf0 R09: 1ffff1100b842a5e
+ R10: dffffc0000000000 R11: ffffed100b842a5f R12: ffff88801e2e5ac0
+ R13: ffff88805c214800 R14: ffff88805c2152e8 R15: 1ffff1100b842a5d
+ FS: 00005555619f6500(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000000020002840 CR3: 00000000247e6000 CR4: 00000000003526f0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ <TASK>
+ genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline]
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0xb14/0xec0 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2542
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline]
+ netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1347
+ netlink_sendmsg+0x8e4/0xcb0 net/netlink/af_netlink.c:1891
+ sock_sendmsg_nosec net/socket.c:711 [inline]
+ __sock_sendmsg+0x221/0x270 net/socket.c:726
+ ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2583
+ ___sys_sendmsg net/socket.c:2637 [inline]
+ __sys_sendmsg+0x269/0x350 net/socket.c:2669
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7f5fe8785d29
+ Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fff571f5558 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007f5fe8975fa0 RCX: 00007f5fe8785d29
+ RDX: 0000000000000000 RSI: 0000000020000480 RDI: 0000000000000007
+ RBP: 00007f5fe8801b08 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007f5fe8975fa0 R14: 00007f5fe8975fa0 R15: 00000000000011f4
+ </TASK>
+
+Here, syzbot managed to set the 'fullmesh' flag on an 'implicit' and
+used -- according to 'id_avail_bitmap' -- endpoint, causing the PM to
+try decrement the local_addr_used counter which is only incremented for
+the 'subflow' endpoint.
+
+Note that 'no type' endpoints -- not 'subflow', 'signal', 'implicit' --
+are fine, because their ID will not be marked as used in the 'id_avail'
+bitmap, and setting 'fullmesh' can help forcing the creation of subflow
+when receiving an ADD_ADDR.
+
+Fixes: 73c762c1f07d ("mptcp: set fullmesh flag in pm_netlink")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+cd16e79c1e45f3fe0377@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/6786ac51.050a0220.216c54.00a6.GAE@google.com
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/540
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20250123-net-mptcp-syzbot-issues-v1-2-af73258a726f@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflicts in pm_netlink.c, because the code has been moved around in
+ commit 6a42477fe449 ("mptcp: update set_flags interfaces"), but the
+ same fix can still be applied at the original place. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -2086,7 +2086,8 @@ static int mptcp_nl_cmd_set_flags(struct
+ return -EINVAL;
+ }
+ if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
+- (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
++ (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL |
++ MPTCP_PM_ADDR_FLAG_IMPLICIT))) {
+ spin_unlock_bh(&pernet->lock);
+ return -EINVAL;
+ }
--- /dev/null
+From stable+bounces-114460-greg=kroah.com@vger.kernel.org Sun Feb 9 18:48:49 2025
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Sun, 9 Feb 2025 18:48:31 +0100
+Subject: mptcp: prevent excessive coalescing on receive
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Paolo Abeni <pabeni@redhat.com>, Mat Martineau <martineau@kernel.org>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20250209174828.3397229-6-matttbe@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 56b824eb49d6258aa0bad09a406ceac3f643cdae upstream.
+
+Currently the skb size after coalescing is only limited by the skb
+layout (the skb must not carry frag_list). A single coalesced skb
+covering several MSS can potentially fill completely the receive
+buffer. In such a case, the snd win will zero until the receive buffer
+will be empty again, affecting tput badly.
+
+Fixes: 8268ed4c9d19 ("mptcp: introduce and use mptcp_try_coalesce()")
+Cc: stable@vger.kernel.org # please delay 2 weeks after 6.13-final release
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20241230-net-mptcp-rbuf-fixes-v1-3-8608af434ceb@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -149,6 +149,7 @@ static bool mptcp_try_coalesce(struct so
+ int delta;
+
+ if (MPTCP_SKB_CB(from)->offset ||
++ ((to->len + from->len) > (sk->sk_rcvbuf >> 3)) ||
+ !skb_try_coalesce(to, from, &fragstolen, &delta))
+ return false;
+
--- /dev/null
+From b0fce54b8c0d8e5f2b4c243c803c5996e73baee8 Mon Sep 17 00:00:00 2001
+From: Su Yue <glass.su@suse.com>
+Date: Mon, 6 Jan 2025 22:06:40 +0800
+Subject: ocfs2: check dir i_size in ocfs2_find_entry
+
+From: Su Yue <glass.su@suse.com>
+
+commit b0fce54b8c0d8e5f2b4c243c803c5996e73baee8 upstream.
+
+syz reports an out of bounds read:
+
+==================================================================
+BUG: KASAN: slab-out-of-bounds in ocfs2_match fs/ocfs2/dir.c:334
+[inline]
+BUG: KASAN: slab-out-of-bounds in ocfs2_search_dirblock+0x283/0x6e0
+fs/ocfs2/dir.c:367
+Read of size 1 at addr ffff88804d8b9982 by task syz-executor.2/14802
+
+CPU: 0 UID: 0 PID: 14802 Comm: syz-executor.2 Not tainted 6.13.0-rc4 #2
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1
+04/01/2014
+Sched_ext: serialise (enabled+all), task: runnable_at=-10ms
+Call Trace:
+<TASK>
+__dump_stack lib/dump_stack.c:94 [inline]
+dump_stack_lvl+0x229/0x350 lib/dump_stack.c:120
+print_address_description mm/kasan/report.c:378 [inline]
+print_report+0x164/0x530 mm/kasan/report.c:489
+kasan_report+0x147/0x180 mm/kasan/report.c:602
+ocfs2_match fs/ocfs2/dir.c:334 [inline]
+ocfs2_search_dirblock+0x283/0x6e0 fs/ocfs2/dir.c:367
+ocfs2_find_entry_id fs/ocfs2/dir.c:414 [inline]
+ocfs2_find_entry+0x1143/0x2db0 fs/ocfs2/dir.c:1078
+ocfs2_find_files_on_disk+0x18e/0x530 fs/ocfs2/dir.c:1981
+ocfs2_lookup_ino_from_name+0xb6/0x110 fs/ocfs2/dir.c:2003
+ocfs2_lookup+0x30a/0xd40 fs/ocfs2/namei.c:122
+lookup_open fs/namei.c:3627 [inline]
+open_last_lookups fs/namei.c:3748 [inline]
+path_openat+0x145a/0x3870 fs/namei.c:3984
+do_filp_open+0xe9/0x1c0 fs/namei.c:4014
+do_sys_openat2+0x135/0x1d0 fs/open.c:1402
+do_sys_open fs/open.c:1417 [inline]
+__do_sys_openat fs/open.c:1433 [inline]
+__se_sys_openat fs/open.c:1428 [inline]
+__x64_sys_openat+0x15d/0x1c0 fs/open.c:1428
+do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+do_syscall_64+0xf6/0x210 arch/x86/entry/common.c:83
+entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f01076903ad
+Code: c3 e8 a7 2b 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89
+f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01
+f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f01084acfc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
+RAX: ffffffffffffffda RBX: 00007f01077cbf80 RCX: 00007f01076903ad
+RDX: 0000000000105042 RSI: 0000000020000080 RDI: ffffffffffffff9c
+RBP: 00007f01077cbf80 R08: 0000000000000000 R09: 0000000000000000
+R10: 00000000000001ff R11: 0000000000000246 R12: 0000000000000000
+R13: 00007f01077cbf80 R14: 00007f010764fc90 R15: 00007f010848d000
+</TASK>
+==================================================================
+
+And a general protection fault in ocfs2_prepare_dir_for_insert:
+
+==================================================================
+loop0: detected capacity change from 0 to 32768
+JBD2: Ignoring recovery information on journal
+ocfs2: Mounting device (7,0) on (node local, slot 0) with ordered data
+mode.
+Oops: general protection fault, probably for non-canonical address
+0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN NOPTI
+KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
+CPU: 0 UID: 0 PID: 5096 Comm: syz-executor792 Not tainted
+6.11.0-rc4-syzkaller-00002-gb0da640826ba #0
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
+1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+RIP: 0010:ocfs2_find_dir_space_id fs/ocfs2/dir.c:3406 [inline]
+RIP: 0010:ocfs2_prepare_dir_for_insert+0x3309/0x5c70 fs/ocfs2/dir.c:4280
+Code: 00 00 e8 2a 25 13 fe e9 ba 06 00 00 e8 20 25 13 fe e9 4f 01 00 00
+e8 16 25 13 fe 49 8d 7f 08 49 8d 5f 09 48 89 f8 48 c1 e8 03 <42> 0f b6
+04 20 84 c0 0f 85 bd 23 00 00 48 89 d8 48 c1 e8 03 42 0f
+RSP: 0018:ffffc9000af9f020 EFLAGS: 00010202
+RAX: 0000000000000001 RBX: 0000000000000009 RCX: ffff88801e27a440
+RDX: 0000000000000000 RSI: 0000000000000400 RDI: 0000000000000008
+RBP: ffffc9000af9f830 R08: ffffffff8380395b R09: ffffffff838090a7
+R10: 0000000000000002 R11: ffff88801e27a440 R12: dffffc0000000000
+R13: ffff88803c660878 R14: f700000000000088 R15: 0000000000000000
+FS: 000055555a677380(0000) GS:ffff888020800000(0000)
+knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000560bce569178 CR3: 000000001de5a000 CR4: 0000000000350ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+ocfs2_mknod+0xcaf/0x2b40 fs/ocfs2/namei.c:292
+vfs_mknod+0x36d/0x3b0 fs/namei.c:4088
+do_mknodat+0x3ec/0x5b0
+__do_sys_mknodat fs/namei.c:4166 [inline]
+__se_sys_mknodat fs/namei.c:4163 [inline]
+__x64_sys_mknodat+0xa7/0xc0 fs/namei.c:4163
+do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f2dafda3a99
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 17 00 00 90 48 89
+f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08
+0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8
+64 89 01 48
+RSP: 002b:00007ffe336a6658 EFLAGS: 00000246 ORIG_RAX:
+0000000000000103
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX:
+00007f2dafda3a99
+RDX: 00000000000021c0 RSI: 0000000020000040 RDI:
+00000000ffffff9c
+RBP: 00007f2dafe1b5f0 R08: 0000000000004480 R09:
+000055555a6784c0
+R10: 0000000000000103 R11: 0000000000000246 R12:
+00007ffe336a6680
+R13: 00007ffe336a68a8 R14: 431bde82d7b634db R15:
+00007f2dafdec03b
+</TASK>
+==================================================================
+
+The two reports are all caused invalid negative i_size of dir inode. For
+ocfs2, dir_inode can't be negative or zero.
+
+Here add a check in which is called by ocfs2_check_dir_for_entry(). It
+fixes the second report as ocfs2_check_dir_for_entry() must be called
+before ocfs2_prepare_dir_for_insert(). Also set a up limit for dir with
+OCFS2_INLINE_DATA_FL. The i_size can't be great than blocksize.
+
+Link: https://lkml.kernel.org/r/20250106140640.92260-1-glass.su@suse.com
+Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
+Link: https://lore.kernel.org/ocfs2-devel/17a04f01.1ae74.19436d003fc.Coremail.stitch@zju.edu.cn/T/#u
+Reported-by: syzbot+5a64828fcc4c2ad9b04f@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/0000000000005894f3062018caf1@google.com/T/
+Signed-off-by: Su Yue <glass.su@suse.com>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+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>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/dir.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+--- a/fs/ocfs2/dir.c
++++ b/fs/ocfs2/dir.c
+@@ -1065,26 +1065,39 @@ int ocfs2_find_entry(const char *name, i
+ {
+ struct buffer_head *bh;
+ struct ocfs2_dir_entry *res_dir = NULL;
++ int ret = 0;
+
+ if (ocfs2_dir_indexed(dir))
+ return ocfs2_find_entry_dx(name, namelen, dir, lookup);
+
++ if (unlikely(i_size_read(dir) <= 0)) {
++ ret = -EFSCORRUPTED;
++ mlog_errno(ret);
++ goto out;
++ }
+ /*
+ * The unindexed dir code only uses part of the lookup
+ * structure, so there's no reason to push it down further
+ * than this.
+ */
+- if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
++ if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
++ if (unlikely(i_size_read(dir) > dir->i_sb->s_blocksize)) {
++ ret = -EFSCORRUPTED;
++ mlog_errno(ret);
++ goto out;
++ }
+ bh = ocfs2_find_entry_id(name, namelen, dir, &res_dir);
+- else
++ } else {
+ bh = ocfs2_find_entry_el(name, namelen, dir, &res_dir);
++ }
+
+ if (bh == NULL)
+ return -ENOENT;
+
+ lookup->dl_leaf_bh = bh;
+ lookup->dl_entry = res_dir;
+- return 0;
++out:
++ return ret;
+ }
+
+ /*
+@@ -2011,6 +2024,7 @@ int ocfs2_lookup_ino_from_name(struct in
+ *
+ * Return 0 if the name does not exist
+ * Return -EEXIST if the directory contains the name
++ * Return -EFSCORRUPTED if found corruption
+ *
+ * Callers should have i_rwsem + a cluster lock on dir
+ */
+@@ -2024,9 +2038,12 @@ int ocfs2_check_dir_for_entry(struct ino
+ trace_ocfs2_check_dir_for_entry(
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
+
+- if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0) {
++ ret = ocfs2_find_entry(name, namelen, dir, &lookup);
++ if (ret == 0) {
+ ret = -EEXIST;
+ mlog_errno(ret);
++ } else if (ret == -ENOENT) {
++ ret = 0;
+ }
+
+ ocfs2_free_dir_lookup_result(&lookup);
--- /dev/null
+From c79a39dc8d060b9e64e8b0fa9d245d44befeefbe Mon Sep 17 00:00:00 2001
+From: Calvin Owens <calvin@wbinvd.org>
+Date: Mon, 11 Nov 2024 20:13:29 -0800
+Subject: pps: Fix a use-after-free
+
+From: Calvin Owens <calvin@wbinvd.org>
+
+commit c79a39dc8d060b9e64e8b0fa9d245d44befeefbe upstream.
+
+On a board running ntpd and gpsd, I'm seeing a consistent use-after-free
+in sys_exit() from gpsd when rebooting:
+
+ pps pps1: removed
+ ------------[ cut here ]------------
+ kobject: '(null)' (00000000db4bec24): is not initialized, yet kobject_put() is being called.
+ WARNING: CPU: 2 PID: 440 at lib/kobject.c:734 kobject_put+0x120/0x150
+ CPU: 2 UID: 299 PID: 440 Comm: gpsd Not tainted 6.11.0-rc6-00308-gb31c44928842 #1
+ Hardware name: Raspberry Pi 4 Model B Rev 1.1 (DT)
+ pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : kobject_put+0x120/0x150
+ lr : kobject_put+0x120/0x150
+ sp : ffffffc0803d3ae0
+ x29: ffffffc0803d3ae0 x28: ffffff8042dc9738 x27: 0000000000000001
+ x26: 0000000000000000 x25: ffffff8042dc9040 x24: ffffff8042dc9440
+ x23: ffffff80402a4620 x22: ffffff8042ef4bd0 x21: ffffff80405cb600
+ x20: 000000000008001b x19: ffffff8040b3b6e0 x18: 0000000000000000
+ x17: 0000000000000000 x16: 0000000000000000 x15: 696e6920746f6e20
+ x14: 7369203a29343263 x13: 205d303434542020 x12: 0000000000000000
+ x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
+ x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000
+ x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
+ x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
+ Call trace:
+ kobject_put+0x120/0x150
+ cdev_put+0x20/0x3c
+ __fput+0x2c4/0x2d8
+ ____fput+0x1c/0x38
+ task_work_run+0x70/0xfc
+ do_exit+0x2a0/0x924
+ do_group_exit+0x34/0x90
+ get_signal+0x7fc/0x8c0
+ do_signal+0x128/0x13b4
+ do_notify_resume+0xdc/0x160
+ el0_svc+0xd4/0xf8
+ el0t_64_sync_handler+0x140/0x14c
+ el0t_64_sync+0x190/0x194
+ ---[ end trace 0000000000000000 ]---
+
+...followed by more symptoms of corruption, with similar stacks:
+
+ refcount_t: underflow; use-after-free.
+ kernel BUG at lib/list_debug.c:62!
+ Kernel panic - not syncing: Oops - BUG: Fatal exception
+
+This happens because pps_device_destruct() frees the pps_device with the
+embedded cdev immediately after calling cdev_del(), but, as the comment
+above cdev_del() notes, fops for previously opened cdevs are still
+callable even after cdev_del() returns. I think this bug has always
+been there: I can't explain why it suddenly started happening every time
+I reboot this particular board.
+
+In commit d953e0e837e6 ("pps: Fix a use-after free bug when
+unregistering a source."), George Spelvin suggested removing the
+embedded cdev. That seems like the simplest way to fix this, so I've
+implemented his suggestion, using __register_chrdev() with pps_idr
+becoming the source of truth for which minor corresponds to which
+device.
+
+But now that pps_idr defines userspace visibility instead of cdev_add(),
+we need to be sure the pps->dev refcount can't reach zero while
+userspace can still find it again. So, the idr_remove() call moves to
+pps_unregister_cdev(), and pps_idr now holds a reference to pps->dev.
+
+ pps_core: source serial1 got cdev (251:1)
+ <...>
+ pps pps1: removed
+ pps_core: unregistering pps1
+ pps_core: deallocating pps1
+
+Fixes: d953e0e837e6 ("pps: Fix a use-after free bug when unregistering a source.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Calvin Owens <calvin@wbinvd.org>
+Reviewed-by: Michal Schmidt <mschmidt@redhat.com>
+Link: https://lore.kernel.org/r/a17975fd5ae99385791929e563f72564edbcf28f.1731383727.git.calvin@wbinvd.org
+Signed-off-by: Calvin Owens <calvin@wbinvd.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pps/clients/pps-gpio.c | 4 -
+ drivers/pps/clients/pps-ktimer.c | 4 -
+ drivers/pps/clients/pps-ldisc.c | 6 -
+ drivers/pps/clients/pps_parport.c | 4 -
+ drivers/pps/kapi.c | 10 +-
+ drivers/pps/kc.c | 10 +-
+ drivers/pps/pps.c | 127 +++++++++++++++++++-------------------
+ drivers/ptp/ptp_ocp.c | 2
+ include/linux/pps_kernel.h | 3
+ 9 files changed, 87 insertions(+), 83 deletions(-)
+
+--- a/drivers/pps/clients/pps-gpio.c
++++ b/drivers/pps/clients/pps-gpio.c
+@@ -214,8 +214,8 @@ static int pps_gpio_probe(struct platfor
+ return -EINVAL;
+ }
+
+- dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n",
+- data->irq);
++ dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n",
++ data->irq);
+
+ return 0;
+ }
+--- a/drivers/pps/clients/pps-ktimer.c
++++ b/drivers/pps/clients/pps-ktimer.c
+@@ -56,7 +56,7 @@ static struct pps_source_info pps_ktimer
+
+ static void __exit pps_ktimer_exit(void)
+ {
+- dev_info(pps->dev, "ktimer PPS source unregistered\n");
++ dev_dbg(&pps->dev, "ktimer PPS source unregistered\n");
+
+ del_timer_sync(&ktimer);
+ pps_unregister_source(pps);
+@@ -74,7 +74,7 @@ static int __init pps_ktimer_init(void)
+ timer_setup(&ktimer, pps_ktimer_event, 0);
+ mod_timer(&ktimer, jiffies + HZ);
+
+- dev_info(pps->dev, "ktimer PPS source registered\n");
++ dev_dbg(&pps->dev, "ktimer PPS source registered\n");
+
+ return 0;
+ }
+--- a/drivers/pps/clients/pps-ldisc.c
++++ b/drivers/pps/clients/pps-ldisc.c
+@@ -32,7 +32,7 @@ static void pps_tty_dcd_change(struct tt
+ pps_event(pps, &ts, active ? PPS_CAPTUREASSERT :
+ PPS_CAPTURECLEAR, NULL);
+
+- dev_dbg(pps->dev, "PPS %s at %lu\n",
++ dev_dbg(&pps->dev, "PPS %s at %lu\n",
+ active ? "assert" : "clear", jiffies);
+ }
+
+@@ -69,7 +69,7 @@ static int pps_tty_open(struct tty_struc
+ goto err_unregister;
+ }
+
+- dev_info(pps->dev, "source \"%s\" added\n", info.path);
++ dev_dbg(&pps->dev, "source \"%s\" added\n", info.path);
+
+ return 0;
+
+@@ -89,7 +89,7 @@ static void pps_tty_close(struct tty_str
+ if (WARN_ON(!pps))
+ return;
+
+- dev_info(pps->dev, "removed\n");
++ dev_info(&pps->dev, "removed\n");
+ pps_unregister_source(pps);
+ }
+
+--- a/drivers/pps/clients/pps_parport.c
++++ b/drivers/pps/clients/pps_parport.c
+@@ -81,7 +81,7 @@ static void parport_irq(void *handle)
+ /* check the signal (no signal means the pulse is lost this time) */
+ if (!signal_is_set(port)) {
+ local_irq_restore(flags);
+- dev_err(dev->pps->dev, "lost the signal\n");
++ dev_err(&dev->pps->dev, "lost the signal\n");
+ goto out_assert;
+ }
+
+@@ -98,7 +98,7 @@ static void parport_irq(void *handle)
+ /* timeout */
+ dev->cw_err++;
+ if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) {
+- dev_err(dev->pps->dev, "disabled clear edge capture after %d"
++ dev_err(&dev->pps->dev, "disabled clear edge capture after %d"
+ " timeouts\n", dev->cw_err);
+ dev->cw = 0;
+ dev->cw_err = 0;
+--- a/drivers/pps/kapi.c
++++ b/drivers/pps/kapi.c
+@@ -41,7 +41,7 @@ static void pps_add_offset(struct pps_kt
+ static void pps_echo_client_default(struct pps_device *pps, int event,
+ void *data)
+ {
+- dev_info(pps->dev, "echo %s %s\n",
++ dev_info(&pps->dev, "echo %s %s\n",
+ event & PPS_CAPTUREASSERT ? "assert" : "",
+ event & PPS_CAPTURECLEAR ? "clear" : "");
+ }
+@@ -112,7 +112,7 @@ struct pps_device *pps_register_source(s
+ goto kfree_pps;
+ }
+
+- dev_info(pps->dev, "new PPS source %s\n", info->name);
++ dev_dbg(&pps->dev, "new PPS source %s\n", info->name);
+
+ return pps;
+
+@@ -166,7 +166,7 @@ void pps_event(struct pps_device *pps, s
+ /* check event type */
+ BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0);
+
+- dev_dbg(pps->dev, "PPS event at %lld.%09ld\n",
++ dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n",
+ (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec);
+
+ timespec_to_pps_ktime(&ts_real, ts->ts_real);
+@@ -188,7 +188,7 @@ void pps_event(struct pps_device *pps, s
+ /* Save the time stamp */
+ pps->assert_tu = ts_real;
+ pps->assert_sequence++;
+- dev_dbg(pps->dev, "capture assert seq #%u\n",
++ dev_dbg(&pps->dev, "capture assert seq #%u\n",
+ pps->assert_sequence);
+
+ captured = ~0;
+@@ -202,7 +202,7 @@ void pps_event(struct pps_device *pps, s
+ /* Save the time stamp */
+ pps->clear_tu = ts_real;
+ pps->clear_sequence++;
+- dev_dbg(pps->dev, "capture clear seq #%u\n",
++ dev_dbg(&pps->dev, "capture clear seq #%u\n",
+ pps->clear_sequence);
+
+ captured = ~0;
+--- a/drivers/pps/kc.c
++++ b/drivers/pps/kc.c
+@@ -43,11 +43,11 @@ int pps_kc_bind(struct pps_device *pps,
+ pps_kc_hardpps_mode = 0;
+ pps_kc_hardpps_dev = NULL;
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+- dev_info(pps->dev, "unbound kernel"
++ dev_info(&pps->dev, "unbound kernel"
+ " consumer\n");
+ } else {
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+- dev_err(pps->dev, "selected kernel consumer"
++ dev_err(&pps->dev, "selected kernel consumer"
+ " is not bound\n");
+ return -EINVAL;
+ }
+@@ -57,11 +57,11 @@ int pps_kc_bind(struct pps_device *pps,
+ pps_kc_hardpps_mode = bind_args->edge;
+ pps_kc_hardpps_dev = pps;
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+- dev_info(pps->dev, "bound kernel consumer: "
++ dev_info(&pps->dev, "bound kernel consumer: "
+ "edge=0x%x\n", bind_args->edge);
+ } else {
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+- dev_err(pps->dev, "another kernel consumer"
++ dev_err(&pps->dev, "another kernel consumer"
+ " is already bound\n");
+ return -EINVAL;
+ }
+@@ -83,7 +83,7 @@ void pps_kc_remove(struct pps_device *pp
+ pps_kc_hardpps_mode = 0;
+ pps_kc_hardpps_dev = NULL;
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+- dev_info(pps->dev, "unbound kernel consumer"
++ dev_info(&pps->dev, "unbound kernel consumer"
+ " on device removal\n");
+ } else
+ spin_unlock_irq(&pps_kc_hardpps_lock);
+--- a/drivers/pps/pps.c
++++ b/drivers/pps/pps.c
+@@ -25,7 +25,7 @@
+ * Local variables
+ */
+
+-static dev_t pps_devt;
++static int pps_major;
+ static struct class *pps_class;
+
+ static DEFINE_MUTEX(pps_idr_lock);
+@@ -62,7 +62,7 @@ static int pps_cdev_pps_fetch(struct pps
+ else {
+ unsigned long ticks;
+
+- dev_dbg(pps->dev, "timeout %lld.%09d\n",
++ dev_dbg(&pps->dev, "timeout %lld.%09d\n",
+ (long long) fdata->timeout.sec,
+ fdata->timeout.nsec);
+ ticks = fdata->timeout.sec * HZ;
+@@ -80,7 +80,7 @@ static int pps_cdev_pps_fetch(struct pps
+
+ /* Check for pending signals */
+ if (err == -ERESTARTSYS) {
+- dev_dbg(pps->dev, "pending signal caught\n");
++ dev_dbg(&pps->dev, "pending signal caught\n");
+ return -EINTR;
+ }
+
+@@ -98,7 +98,7 @@ static long pps_cdev_ioctl(struct file *
+
+ switch (cmd) {
+ case PPS_GETPARAMS:
+- dev_dbg(pps->dev, "PPS_GETPARAMS\n");
++ dev_dbg(&pps->dev, "PPS_GETPARAMS\n");
+
+ spin_lock_irq(&pps->lock);
+
+@@ -114,7 +114,7 @@ static long pps_cdev_ioctl(struct file *
+ break;
+
+ case PPS_SETPARAMS:
+- dev_dbg(pps->dev, "PPS_SETPARAMS\n");
++ dev_dbg(&pps->dev, "PPS_SETPARAMS\n");
+
+ /* Check the capabilities */
+ if (!capable(CAP_SYS_TIME))
+@@ -124,14 +124,14 @@ static long pps_cdev_ioctl(struct file *
+ if (err)
+ return -EFAULT;
+ if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) {
+- dev_dbg(pps->dev, "capture mode unspecified (%x)\n",
++ dev_dbg(&pps->dev, "capture mode unspecified (%x)\n",
+ params.mode);
+ return -EINVAL;
+ }
+
+ /* Check for supported capabilities */
+ if ((params.mode & ~pps->info.mode) != 0) {
+- dev_dbg(pps->dev, "unsupported capabilities (%x)\n",
++ dev_dbg(&pps->dev, "unsupported capabilities (%x)\n",
+ params.mode);
+ return -EINVAL;
+ }
+@@ -144,7 +144,7 @@ static long pps_cdev_ioctl(struct file *
+ /* Restore the read only parameters */
+ if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
+ /* section 3.3 of RFC 2783 interpreted */
+- dev_dbg(pps->dev, "time format unspecified (%x)\n",
++ dev_dbg(&pps->dev, "time format unspecified (%x)\n",
+ params.mode);
+ pps->params.mode |= PPS_TSFMT_TSPEC;
+ }
+@@ -165,7 +165,7 @@ static long pps_cdev_ioctl(struct file *
+ break;
+
+ case PPS_GETCAP:
+- dev_dbg(pps->dev, "PPS_GETCAP\n");
++ dev_dbg(&pps->dev, "PPS_GETCAP\n");
+
+ err = put_user(pps->info.mode, iuarg);
+ if (err)
+@@ -176,7 +176,7 @@ static long pps_cdev_ioctl(struct file *
+ case PPS_FETCH: {
+ struct pps_fdata fdata;
+
+- dev_dbg(pps->dev, "PPS_FETCH\n");
++ dev_dbg(&pps->dev, "PPS_FETCH\n");
+
+ err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata));
+ if (err)
+@@ -206,7 +206,7 @@ static long pps_cdev_ioctl(struct file *
+ case PPS_KC_BIND: {
+ struct pps_bind_args bind_args;
+
+- dev_dbg(pps->dev, "PPS_KC_BIND\n");
++ dev_dbg(&pps->dev, "PPS_KC_BIND\n");
+
+ /* Check the capabilities */
+ if (!capable(CAP_SYS_TIME))
+@@ -218,7 +218,7 @@ static long pps_cdev_ioctl(struct file *
+
+ /* Check for supported capabilities */
+ if ((bind_args.edge & ~pps->info.mode) != 0) {
+- dev_err(pps->dev, "unsupported capabilities (%x)\n",
++ dev_err(&pps->dev, "unsupported capabilities (%x)\n",
+ bind_args.edge);
+ return -EINVAL;
+ }
+@@ -227,7 +227,7 @@ static long pps_cdev_ioctl(struct file *
+ if (bind_args.tsformat != PPS_TSFMT_TSPEC ||
+ (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 ||
+ bind_args.consumer != PPS_KC_HARDPPS) {
+- dev_err(pps->dev, "invalid kernel consumer bind"
++ dev_err(&pps->dev, "invalid kernel consumer bind"
+ " parameters (%x)\n", bind_args.edge);
+ return -EINVAL;
+ }
+@@ -259,7 +259,7 @@ static long pps_cdev_compat_ioctl(struct
+ struct pps_fdata fdata;
+ int err;
+
+- dev_dbg(pps->dev, "PPS_FETCH\n");
++ dev_dbg(&pps->dev, "PPS_FETCH\n");
+
+ err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat));
+ if (err)
+@@ -296,20 +296,36 @@ static long pps_cdev_compat_ioctl(struct
+ #define pps_cdev_compat_ioctl NULL
+ #endif
+
++static struct pps_device *pps_idr_get(unsigned long id)
++{
++ struct pps_device *pps;
++
++ mutex_lock(&pps_idr_lock);
++ pps = idr_find(&pps_idr, id);
++ if (pps)
++ get_device(&pps->dev);
++
++ mutex_unlock(&pps_idr_lock);
++ return pps;
++}
++
+ static int pps_cdev_open(struct inode *inode, struct file *file)
+ {
+- struct pps_device *pps = container_of(inode->i_cdev,
+- struct pps_device, cdev);
++ struct pps_device *pps = pps_idr_get(iminor(inode));
++
++ if (!pps)
++ return -ENODEV;
++
+ file->private_data = pps;
+- kobject_get(&pps->dev->kobj);
+ return 0;
+ }
+
+ static int pps_cdev_release(struct inode *inode, struct file *file)
+ {
+- struct pps_device *pps = container_of(inode->i_cdev,
+- struct pps_device, cdev);
+- kobject_put(&pps->dev->kobj);
++ struct pps_device *pps = file->private_data;
++
++ WARN_ON(pps->id != iminor(inode));
++ put_device(&pps->dev);
+ return 0;
+ }
+
+@@ -332,22 +348,13 @@ static void pps_device_destruct(struct d
+ {
+ struct pps_device *pps = dev_get_drvdata(dev);
+
+- cdev_del(&pps->cdev);
+-
+- /* Now we can release the ID for re-use */
+ pr_debug("deallocating pps%d\n", pps->id);
+- mutex_lock(&pps_idr_lock);
+- idr_remove(&pps_idr, pps->id);
+- mutex_unlock(&pps_idr_lock);
+-
+- kfree(dev);
+ kfree(pps);
+ }
+
+ int pps_register_cdev(struct pps_device *pps)
+ {
+ int err;
+- dev_t devt;
+
+ mutex_lock(&pps_idr_lock);
+ /*
+@@ -364,40 +371,29 @@ int pps_register_cdev(struct pps_device
+ goto out_unlock;
+ }
+ pps->id = err;
+- mutex_unlock(&pps_idr_lock);
+-
+- devt = MKDEV(MAJOR(pps_devt), pps->id);
+-
+- cdev_init(&pps->cdev, &pps_cdev_fops);
+- pps->cdev.owner = pps->info.owner;
+
+- err = cdev_add(&pps->cdev, devt, 1);
+- if (err) {
+- pr_err("%s: failed to add char device %d:%d\n",
+- pps->info.name, MAJOR(pps_devt), pps->id);
++ pps->dev.class = pps_class;
++ pps->dev.parent = pps->info.dev;
++ pps->dev.devt = MKDEV(pps_major, pps->id);
++ dev_set_drvdata(&pps->dev, pps);
++ dev_set_name(&pps->dev, "pps%d", pps->id);
++ err = device_register(&pps->dev);
++ if (err)
+ goto free_idr;
+- }
+- pps->dev = device_create(pps_class, pps->info.dev, devt, pps,
+- "pps%d", pps->id);
+- if (IS_ERR(pps->dev)) {
+- err = PTR_ERR(pps->dev);
+- goto del_cdev;
+- }
+
+ /* Override the release function with our own */
+- pps->dev->release = pps_device_destruct;
++ pps->dev.release = pps_device_destruct;
+
+- pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
+- MAJOR(pps_devt), pps->id);
++ pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major,
++ pps->id);
+
++ get_device(&pps->dev);
++ mutex_unlock(&pps_idr_lock);
+ return 0;
+
+-del_cdev:
+- cdev_del(&pps->cdev);
+-
+ free_idr:
+- mutex_lock(&pps_idr_lock);
+ idr_remove(&pps_idr, pps->id);
++ put_device(&pps->dev);
+ out_unlock:
+ mutex_unlock(&pps_idr_lock);
+ return err;
+@@ -407,7 +403,13 @@ void pps_unregister_cdev(struct pps_devi
+ {
+ pr_debug("unregistering pps%d\n", pps->id);
+ pps->lookup_cookie = NULL;
+- device_destroy(pps_class, pps->dev->devt);
++ device_destroy(pps_class, pps->dev.devt);
++
++ /* Now we can release the ID for re-use */
++ mutex_lock(&pps_idr_lock);
++ idr_remove(&pps_idr, pps->id);
++ put_device(&pps->dev);
++ mutex_unlock(&pps_idr_lock);
+ }
+
+ /*
+@@ -427,6 +429,11 @@ void pps_unregister_cdev(struct pps_devi
+ * so that it will not be used again, even if the pps device cannot
+ * be removed from the idr due to pending references holding the minor
+ * number in use.
++ *
++ * Since pps_idr holds a reference to the device, the returned
++ * pps_device is guaranteed to be valid until pps_unregister_cdev() is
++ * called on it. But after calling pps_unregister_cdev(), it may be
++ * freed at any time.
+ */
+ struct pps_device *pps_lookup_dev(void const *cookie)
+ {
+@@ -449,13 +456,11 @@ EXPORT_SYMBOL(pps_lookup_dev);
+ static void __exit pps_exit(void)
+ {
+ class_destroy(pps_class);
+- unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES);
++ __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps");
+ }
+
+ static int __init pps_init(void)
+ {
+- int err;
+-
+ pps_class = class_create(THIS_MODULE, "pps");
+ if (IS_ERR(pps_class)) {
+ pr_err("failed to allocate class\n");
+@@ -463,8 +468,9 @@ static int __init pps_init(void)
+ }
+ pps_class->dev_groups = pps_groups;
+
+- err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps");
+- if (err < 0) {
++ pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps",
++ &pps_cdev_fops);
++ if (pps_major < 0) {
+ pr_err("failed to allocate char device region\n");
+ goto remove_class;
+ }
+@@ -477,8 +483,7 @@ static int __init pps_init(void)
+
+ remove_class:
+ class_destroy(pps_class);
+-
+- return err;
++ return pps_major;
+ }
+
+ subsys_initcall(pps_init);
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -3589,7 +3589,7 @@ ptp_ocp_complete(struct ptp_ocp *bp)
+
+ pps = pps_lookup_dev(bp->ptp);
+ if (pps)
+- ptp_ocp_symlink(bp, pps->dev, "pps");
++ ptp_ocp_symlink(bp, &pps->dev, "pps");
+
+ ptp_ocp_debugfs_add_device(bp);
+
+--- a/include/linux/pps_kernel.h
++++ b/include/linux/pps_kernel.h
+@@ -56,8 +56,7 @@ struct pps_device {
+
+ unsigned int id; /* PPS source unique ID */
+ void const *lookup_cookie; /* For pps_lookup_dev() only */
+- struct cdev cdev;
+- struct device *dev;
++ struct device dev;
+ struct fasync_struct *async_queue; /* fasync method */
+ spinlock_t lock;
+ };
--- /dev/null
+From stable+bounces-114131-greg=kroah.com@vger.kernel.org Thu Feb 6 17:21:32 2025
+From: Koichiro Den <koichiro.den@canonical.com>
+Date: Fri, 7 Feb 2025 01:20:54 +0900
+Subject: Revert "btrfs: avoid monopolizing a core when activating a swap file"
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: wqu@suse.com, fdmanana@suse.com, dsterba@suse.com
+Message-ID: <20250206162055.1387169-1-koichiro.den@canonical.com>
+
+From: Koichiro Den <koichiro.den@canonical.com>
+
+This reverts commit bb8e287f596b62fac18ed84cc03a9f1752f6b3b8.
+
+The backport for linux-6.1.y, commit bb8e287f596b ("btrfs: avoid
+monopolizing a core when activating a swap file"), inserted
+cond_resched() in the wrong location.
+
+Revert it now; a subsequent commit will re-backport the original patch.
+
+Fixes: bb8e287f596b ("btrfs: avoid monopolizing a core when activating a swap file") # linux-6.1.y
+Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -7387,8 +7387,6 @@ noinline int can_nocow_extent(struct ino
+ ret = -EAGAIN;
+ goto out;
+ }
+-
+- cond_resched();
+ }
+
+ if (orig_start)
x86-amd_nb-restrict-init-function-to-amd-based-syste.patch
drm-virtio-new-fence-for-every-plane-update.patch
printk-fix-signed-integer-overflow-when-defining-log.patch
-drm-sti-hdmi-use-eld_mutex-to-protect-access-to-conn.patch
drm-amd-display-fix-mode-cutoff-in-dsc-passthrough-t.patch
drm-bridge-it6505-change-definition-max_hdcp_down_st.patch
drm-bridge-it6505-fix-hdcp-bstatus-check.patch
mips-ftrace-declare-ftrace_get_parent_ra_addr-as-static.patch
net-ncsi-use-dev_set_mac_address-for-get-mc-mac-address-handling.patch
gpio-xilinx-remove-excess-kernel-doc.patch
+ocfs2-check-dir-i_size-in-ocfs2_find_entry.patch
+ext4-filesystems-without-casefold-feature-cannot-be-mounted-with-siphash.patch
+cachefiles-fix-null-pointer-dereference-in-object-file.patch
+mptcp-pm-only-set-fullmesh-for-subflow-endp.patch
+mptcp-prevent-excessive-coalescing-on-receive.patch
+tty-xilinx_uartps-split-sysrq-handling.patch
+maple_tree-fix-static-analyser-cppcheck-issue.patch
+maple_tree-simplify-split-calculation.patch
+pps-fix-a-use-after-free.patch
+revert-btrfs-avoid-monopolizing-a-core-when-activating-a-swap-file.patch
+btrfs-avoid-monopolizing-a-core-when-activating-a-swap-file.patch
--- /dev/null
+From b06f388994500297bb91be60ffaf6825ecfd2afe Mon Sep 17 00:00:00 2001
+From: Sean Anderson <sean.anderson@linux.dev>
+Date: Fri, 10 Jan 2025 16:38:22 -0500
+Subject: tty: xilinx_uartps: split sysrq handling
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+commit b06f388994500297bb91be60ffaf6825ecfd2afe upstream.
+
+lockdep detects the following circular locking dependency:
+
+CPU 0 CPU 1
+========================== ============================
+cdns_uart_isr() printk()
+ uart_port_lock(port) console_lock()
+ cdns_uart_console_write()
+ if (!port->sysrq)
+ uart_port_lock(port)
+ uart_handle_break()
+ port->sysrq = ...
+ uart_handle_sysrq_char()
+ printk()
+ console_lock()
+
+The fixed commit attempts to avoid this situation by only taking the
+port lock in cdns_uart_console_write if port->sysrq unset. However, if
+(as shown above) cdns_uart_console_write runs before port->sysrq is set,
+then it will try to take the port lock anyway. This may result in a
+deadlock.
+
+Fix this by splitting sysrq handling into two parts. We use the prepare
+helper under the port lock and defer handling until we release the lock.
+
+Fixes: 74ea66d4ca06 ("tty: xuartps: Improve sysrq handling")
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Cc: stable@vger.kernel.org # c980248179d: serial: xilinx_uartps: Use port lock wrappers
+Acked-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20250110213822.2107462-1-sean.anderson@linux.dev
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/xilinx_uartps.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/xilinx_uartps.c
++++ b/drivers/tty/serial/xilinx_uartps.c
+@@ -268,7 +268,7 @@ static void cdns_uart_handle_rx(void *de
+ continue;
+ }
+
+- if (uart_handle_sysrq_char(port, data))
++ if (uart_prepare_sysrq_char(port, data))
+ continue;
+
+ if (is_rxbs_support) {
+@@ -371,7 +371,7 @@ static irqreturn_t cdns_uart_isr(int irq
+ !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS))
+ cdns_uart_handle_rx(dev_id, isrstatus);
+
+- spin_unlock(&port->lock);
++ uart_unlock_and_check_sysrq(port);
+ return IRQ_HANDLED;
+ }
+
+@@ -1231,10 +1231,8 @@ static void cdns_uart_console_write(stru
+ unsigned int imr, ctrl;
+ int locked = 1;
+
+- if (port->sysrq)
+- locked = 0;
+- else if (oops_in_progress)
+- locked = spin_trylock_irqsave(&port->lock, flags);
++ if (oops_in_progress)
++ locked = uart_port_trylock_irqsave(port, &flags);
+ else
+ spin_lock_irqsave(&port->lock, flags);
+