From: Greg Kroah-Hartman Date: Thu, 13 Jun 2024 11:02:55 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v4.19.316~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=35110da67ee50a12bfcddd20f4c87928a0b7fb79;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch edac-igen6-convert-pcibios_-return-codes-to-errnos.patch nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch nfs-fix-undefined-behavior-in-nfs_block_bits.patch powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch --- diff --git a/queue-6.1/btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch b/queue-6.1/btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch new file mode 100644 index 00000000000..314dfc6ae7e --- /dev/null +++ b/queue-6.1/btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch @@ -0,0 +1,218 @@ +From 9d274c19a71b3a276949933859610721a453946b Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Fri, 24 May 2024 13:58:11 -0700 +Subject: btrfs: fix crash on racing fsync and size-extending write into prealloc + +From: Omar Sandoval + +commit 9d274c19a71b3a276949933859610721a453946b upstream. + +We have been seeing crashes on duplicate keys in +btrfs_set_item_key_safe(): + + BTRFS critical (device vdb): slot 4 key (450 108 8192) new key (450 108 8192) + ------------[ cut here ]------------ + kernel BUG at fs/btrfs/ctree.c:2620! + invalid opcode: 0000 [#1] PREEMPT SMP PTI + CPU: 0 PID: 3139 Comm: xfs_io Kdump: loaded Not tainted 6.9.0 #6 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-2.fc40 04/01/2014 + RIP: 0010:btrfs_set_item_key_safe+0x11f/0x290 [btrfs] + +With the following stack trace: + + #0 btrfs_set_item_key_safe (fs/btrfs/ctree.c:2620:4) + #1 btrfs_drop_extents (fs/btrfs/file.c:411:4) + #2 log_one_extent (fs/btrfs/tree-log.c:4732:9) + #3 btrfs_log_changed_extents (fs/btrfs/tree-log.c:4955:9) + #4 btrfs_log_inode (fs/btrfs/tree-log.c:6626:9) + #5 btrfs_log_inode_parent (fs/btrfs/tree-log.c:7070:8) + #6 btrfs_log_dentry_safe (fs/btrfs/tree-log.c:7171:8) + #7 btrfs_sync_file (fs/btrfs/file.c:1933:8) + #8 vfs_fsync_range (fs/sync.c:188:9) + #9 vfs_fsync (fs/sync.c:202:9) + #10 do_fsync (fs/sync.c:212:9) + #11 __do_sys_fdatasync (fs/sync.c:225:9) + #12 __se_sys_fdatasync (fs/sync.c:223:1) + #13 __x64_sys_fdatasync (fs/sync.c:223:1) + #14 do_syscall_x64 (arch/x86/entry/common.c:52:14) + #15 do_syscall_64 (arch/x86/entry/common.c:83:7) + #16 entry_SYSCALL_64+0xaf/0x14c (arch/x86/entry/entry_64.S:121) + +So we're logging a changed extent from fsync, which is splitting an +extent in the log tree. But this split part already exists in the tree, +triggering the BUG(). + +This is the state of the log tree at the time of the crash, dumped with +drgn (https://github.com/osandov/drgn/blob/main/contrib/btrfs_tree.py) +to get more details than btrfs_print_leaf() gives us: + + >>> print_extent_buffer(prog.crashed_thread().stack_trace()[0]["eb"]) + leaf 33439744 level 0 items 72 generation 9 owner 18446744073709551610 + leaf 33439744 flags 0x100000000000000 + fs uuid e5bd3946-400c-4223-8923-190ef1f18677 + chunk uuid d58cb17e-6d02-494a-829a-18b7d8a399da + item 0 key (450 INODE_ITEM 0) itemoff 16123 itemsize 160 + generation 7 transid 9 size 8192 nbytes 8473563889606862198 + block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 + sequence 204 flags 0x10(PREALLOC) + atime 1716417703.220000000 (2024-05-22 15:41:43) + ctime 1716417704.983333333 (2024-05-22 15:41:44) + mtime 1716417704.983333333 (2024-05-22 15:41:44) + otime 17592186044416.000000000 (559444-03-08 01:40:16) + item 1 key (450 INODE_REF 256) itemoff 16110 itemsize 13 + index 195 namelen 3 name: 193 + item 2 key (450 XATTR_ITEM 1640047104) itemoff 16073 itemsize 37 + location key (0 UNKNOWN.0 0) type XATTR + transid 7 data_len 1 name_len 6 + name: user.a + data a + item 3 key (450 EXTENT_DATA 0) itemoff 16020 itemsize 53 + generation 9 type 1 (regular) + extent data disk byte 303144960 nr 12288 + extent data offset 0 nr 4096 ram 12288 + extent compression 0 (none) + item 4 key (450 EXTENT_DATA 4096) itemoff 15967 itemsize 53 + generation 9 type 2 (prealloc) + prealloc data disk byte 303144960 nr 12288 + prealloc data offset 4096 nr 8192 + item 5 key (450 EXTENT_DATA 8192) itemoff 15914 itemsize 53 + generation 9 type 2 (prealloc) + prealloc data disk byte 303144960 nr 12288 + prealloc data offset 8192 nr 4096 + ... + +So the real problem happened earlier: notice that items 4 (4k-12k) and 5 +(8k-12k) overlap. Both are prealloc extents. Item 4 straddles i_size and +item 5 starts at i_size. + +Here is the state of the filesystem tree at the time of the crash: + + >>> root = prog.crashed_thread().stack_trace()[2]["inode"].root + >>> ret, nodes, slots = btrfs_search_slot(root, BtrfsKey(450, 0, 0)) + >>> print_extent_buffer(nodes[0]) + leaf 30425088 level 0 items 184 generation 9 owner 5 + leaf 30425088 flags 0x100000000000000 + fs uuid e5bd3946-400c-4223-8923-190ef1f18677 + chunk uuid d58cb17e-6d02-494a-829a-18b7d8a399da + ... + item 179 key (450 INODE_ITEM 0) itemoff 4907 itemsize 160 + generation 7 transid 7 size 4096 nbytes 12288 + block group 0 mode 100600 links 1 uid 0 gid 0 rdev 0 + sequence 6 flags 0x10(PREALLOC) + atime 1716417703.220000000 (2024-05-22 15:41:43) + ctime 1716417703.220000000 (2024-05-22 15:41:43) + mtime 1716417703.220000000 (2024-05-22 15:41:43) + otime 1716417703.220000000 (2024-05-22 15:41:43) + item 180 key (450 INODE_REF 256) itemoff 4894 itemsize 13 + index 195 namelen 3 name: 193 + item 181 key (450 XATTR_ITEM 1640047104) itemoff 4857 itemsize 37 + location key (0 UNKNOWN.0 0) type XATTR + transid 7 data_len 1 name_len 6 + name: user.a + data a + item 182 key (450 EXTENT_DATA 0) itemoff 4804 itemsize 53 + generation 9 type 1 (regular) + extent data disk byte 303144960 nr 12288 + extent data offset 0 nr 8192 ram 12288 + extent compression 0 (none) + item 183 key (450 EXTENT_DATA 8192) itemoff 4751 itemsize 53 + generation 9 type 2 (prealloc) + prealloc data disk byte 303144960 nr 12288 + prealloc data offset 8192 nr 4096 + +Item 5 in the log tree corresponds to item 183 in the filesystem tree, +but nothing matches item 4. Furthermore, item 183 is the last item in +the leaf. + +btrfs_log_prealloc_extents() is responsible for logging prealloc extents +beyond i_size. It first truncates any previously logged prealloc extents +that start beyond i_size. Then, it walks the filesystem tree and copies +the prealloc extent items to the log tree. + +If it hits the end of a leaf, then it calls btrfs_next_leaf(), which +unlocks the tree and does another search. However, while the filesystem +tree is unlocked, an ordered extent completion may modify the tree. In +particular, it may insert an extent item that overlaps with an extent +item that was already copied to the log tree. + +This may manifest in several ways depending on the exact scenario, +including an EEXIST error that is silently translated to a full sync, +overlapping items in the log tree, or this crash. This particular crash +is triggered by the following sequence of events: + +- Initially, the file has i_size=4k, a regular extent from 0-4k, and a + prealloc extent beyond i_size from 4k-12k. The prealloc extent item is + the last item in its B-tree leaf. +- The file is fsync'd, which copies its inode item and both extent items + to the log tree. +- An xattr is set on the file, which sets the + BTRFS_INODE_COPY_EVERYTHING flag. +- The range 4k-8k in the file is written using direct I/O. i_size is + extended to 8k, but the ordered extent is still in flight. +- The file is fsync'd. Since BTRFS_INODE_COPY_EVERYTHING is set, this + calls copy_inode_items_to_log(), which calls + btrfs_log_prealloc_extents(). +- btrfs_log_prealloc_extents() finds the 4k-12k prealloc extent in the + filesystem tree. Since it starts before i_size, it skips it. Since it + is the last item in its B-tree leaf, it calls btrfs_next_leaf(). +- btrfs_next_leaf() unlocks the path. +- The ordered extent completion runs, which converts the 4k-8k part of + the prealloc extent to written and inserts the remaining prealloc part + from 8k-12k. +- btrfs_next_leaf() does a search and finds the new prealloc extent + 8k-12k. +- btrfs_log_prealloc_extents() copies the 8k-12k prealloc extent into + the log tree. Note that it overlaps with the 4k-12k prealloc extent + that was copied to the log tree by the first fsync. +- fsync calls btrfs_log_changed_extents(), which tries to log the 4k-8k + extent that was written. +- This tries to drop the range 4k-8k in the log tree, which requires + adjusting the start of the 4k-12k prealloc extent in the log tree to + 8k. +- btrfs_set_item_key_safe() sees that there is already an extent + starting at 8k in the log tree and calls BUG(). + +Fix this by detecting when we're about to insert an overlapping file +extent item in the log tree and truncating the part that would overlap. + +CC: stable@vger.kernel.org # 6.1+ +Reviewed-by: Filipe Manana +Signed-off-by: Omar Sandoval +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/tree-log.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4845,18 +4845,23 @@ static int btrfs_log_prealloc_extents(st + path->slots[0]++; + continue; + } +- if (!dropped_extents) { +- /* +- * Avoid logging extent items logged in past fsync calls +- * and leading to duplicate keys in the log tree. +- */ ++ /* ++ * Avoid overlapping items in the log tree. The first time we ++ * get here, get rid of everything from a past fsync. After ++ * that, if the current extent starts before the end of the last ++ * extent we copied, truncate the last one. This can happen if ++ * an ordered extent completion modifies the subvolume tree ++ * while btrfs_next_leaf() has the tree unlocked. ++ */ ++ if (!dropped_extents || key.offset < truncate_offset) { + ret = truncate_inode_items(trans, root->log_root, inode, +- truncate_offset, ++ min(key.offset, truncate_offset), + BTRFS_EXTENT_DATA_KEY); + if (ret) + goto out; + dropped_extents = true; + } ++ truncate_offset = btrfs_file_extent_end(path); + if (ins_nr == 0) + start_slot = slot; + ins_nr++; diff --git a/queue-6.1/edac-igen6-convert-pcibios_-return-codes-to-errnos.patch b/queue-6.1/edac-igen6-convert-pcibios_-return-codes-to-errnos.patch new file mode 100644 index 00000000000..475d77868ca --- /dev/null +++ b/queue-6.1/edac-igen6-convert-pcibios_-return-codes-to-errnos.patch @@ -0,0 +1,51 @@ +From f8367a74aebf88dc8b58a0db6a6c90b4cb8fc9d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= +Date: Mon, 27 May 2024 16:22:35 +0300 +Subject: EDAC/igen6: Convert PCIBIOS_* return codes to errnos +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +commit f8367a74aebf88dc8b58a0db6a6c90b4cb8fc9d3 upstream. + +errcmd_enable_error_reporting() uses pci_{read,write}_config_word() +that return PCIBIOS_* codes. The return code is then returned all the +way into the probe function igen6_probe() that returns it as is. The +probe functions, however, should return normal errnos. + +Convert PCIBIOS_* returns code using pcibios_err_to_errno() into normal +errno before returning it from errcmd_enable_error_reporting(). + +Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC") +Signed-off-by: Ilpo Järvinen +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Qiuxu Zhuo +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20240527132236.13875-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/edac/igen6_edac.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/edac/igen6_edac.c ++++ b/drivers/edac/igen6_edac.c +@@ -627,7 +627,7 @@ static int errcmd_enable_error_reporting + + rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd); + if (rc) +- return rc; ++ return pcibios_err_to_errno(rc); + + if (enable) + errcmd |= ERRCMD_CE | ERRSTS_UE; +@@ -636,7 +636,7 @@ static int errcmd_enable_error_reporting + + rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd); + if (rc) +- return rc; ++ return pcibios_err_to_errno(rc); + + return 0; + } diff --git a/queue-6.1/nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch b/queue-6.1/nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch new file mode 100644 index 00000000000..dec2c9b6f09 --- /dev/null +++ b/queue-6.1/nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch @@ -0,0 +1,41 @@ +From f06d1b10cb016d5aaecdb1804fefca025387bd10 Mon Sep 17 00:00:00 2001 +From: Anna Schumaker +Date: Thu, 25 Apr 2024 16:24:29 -0400 +Subject: NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS + +From: Anna Schumaker + +commit f06d1b10cb016d5aaecdb1804fefca025387bd10 upstream. + +Olga showed me a case where the client was sending multiple READ_PLUS +calls to the server in parallel, and the server replied +NFS4ERR_OPNOTSUPP to each. The client would fall back to READ for the +first reply, but fail to retry the other calls. + +I fix this by removing the test for NFS_CAP_READ_PLUS in +nfs4_read_plus_not_supported(). This allows us to reschedule any +READ_PLUS call that has a NFS4ERR_OPNOTSUPP return value, even after the +capability has been cleared. + +Reported-by: Olga Kornievskaia +Fixes: c567552612ec ("NFS: Add READ_PLUS data segment support") +Cc: stable@vger.kernel.org # v5.10+ +Signed-off-by: Anna Schumaker +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/nfs4proc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5441,7 +5441,7 @@ static bool nfs4_read_plus_not_supported + struct rpc_message *msg = &task->tk_msg; + + if (msg->rpc_proc == &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS] && +- server->caps & NFS_CAP_READ_PLUS && task->tk_status == -ENOTSUPP) { ++ task->tk_status == -ENOTSUPP) { + server->caps &= ~NFS_CAP_READ_PLUS; + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; + rpc_restart_call_prepare(task); diff --git a/queue-6.1/nfs-fix-undefined-behavior-in-nfs_block_bits.patch b/queue-6.1/nfs-fix-undefined-behavior-in-nfs_block_bits.patch new file mode 100644 index 00000000000..eaaa8b57fd0 --- /dev/null +++ b/queue-6.1/nfs-fix-undefined-behavior-in-nfs_block_bits.patch @@ -0,0 +1,38 @@ +From 3c0a2e0b0ae661457c8505fecc7be5501aa7a715 Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Fri, 10 May 2024 23:24:04 +0300 +Subject: nfs: fix undefined behavior in nfs_block_bits() + +From: Sergey Shtylyov + +commit 3c0a2e0b0ae661457c8505fecc7be5501aa7a715 upstream. + +Shifting *signed int* typed constant 1 left by 31 bits causes undefined +behavior. Specify the correct *unsigned long* type by using 1UL instead. + +Found by Linux Verification Center (linuxtesting.org) with the Svace static +analysis tool. + +Cc: stable@vger.kernel.org +Signed-off-by: Sergey Shtylyov +Reviewed-by: Benjamin Coddington +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfs/internal.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfs/internal.h ++++ b/fs/nfs/internal.h +@@ -695,9 +695,9 @@ unsigned long nfs_block_bits(unsigned lo + if ((bsize & (bsize - 1)) || nrbitsp) { + unsigned char nrbits; + +- for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--) ++ for (nrbits = 31; nrbits && !(bsize & (1UL << nrbits)); nrbits--) + ; +- bsize = 1 << nrbits; ++ bsize = 1UL << nrbits; + if (nrbitsp) + *nrbitsp = nrbits; + } diff --git a/queue-6.1/powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch b/queue-6.1/powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch new file mode 100644 index 00000000000..df0011770c5 --- /dev/null +++ b/queue-6.1/powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch @@ -0,0 +1,138 @@ +From b1e7cee96127468c2483cf10c2899c9b5cf79bf8 Mon Sep 17 00:00:00 2001 +From: Puranjay Mohan +Date: Mon, 13 May 2024 10:02:48 +0000 +Subject: powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH + +From: Puranjay Mohan + +commit b1e7cee96127468c2483cf10c2899c9b5cf79bf8 upstream. + +The Linux Kernel Memory Model [1][2] requires RMW operations that have a +return value to be fully ordered. + +BPF atomic operations with BPF_FETCH (including BPF_XCHG and +BPF_CMPXCHG) return a value back so they need to be JITed to fully +ordered operations. POWERPC currently emits relaxed operations for +these. + +We can show this by running the following litmus-test: + + PPC SB+atomic_add+fetch + + { + 0:r0=x; (* dst reg assuming offset is 0 *) + 0:r1=2; (* src reg *) + 0:r2=1; + 0:r4=y; (* P0 writes to this, P1 reads this *) + 0:r5=z; (* P1 writes to this, P0 reads this *) + 0:r6=0; + + 1:r2=1; + 1:r4=y; + 1:r5=z; + } + + P0 | P1 ; + stw r2, 0(r4) | stw r2,0(r5) ; + | ; + loop:lwarx r3, r6, r0 | ; + mr r8, r3 | ; + add r3, r3, r1 | sync ; + stwcx. r3, r6, r0 | ; + bne loop | ; + mr r1, r8 | ; + | ; + lwa r7, 0(r5) | lwa r7,0(r4) ; + + ~exists(0:r7=0 /\ 1:r7=0) + + Witnesses + Positive: 9 Negative: 3 + Condition ~exists (0:r7=0 /\ 1:r7=0) + Observation SB+atomic_add+fetch Sometimes 3 9 + +This test shows that the older store in P0 is reordered with a newer +load to a different address. Although there is a RMW operation with +fetch between them. Adding a sync before and after RMW fixes the issue: + + Witnesses + Positive: 9 Negative: 0 + Condition ~exists (0:r7=0 /\ 1:r7=0) + Observation SB+atomic_add+fetch Never 0 9 + +[1] https://www.kernel.org/doc/Documentation/memory-barriers.txt +[2] https://www.kernel.org/doc/Documentation/atomic_t.txt + +Fixes: aea7ef8a82c0 ("powerpc/bpf/32: add support for BPF_ATOMIC bitwise operations") +Fixes: 2d9206b22743 ("powerpc/bpf/32: Add instructions for atomic_[cmp]xchg") +Fixes: dbe6e2456fb0 ("powerpc/bpf/64: add support for atomic fetch operations") +Fixes: 1e82dfaa7819 ("powerpc/bpf/64: Add instructions for atomic_[cmp]xchg") +Cc: stable@vger.kernel.org # v6.0+ +Signed-off-by: Puranjay Mohan +Reviewed-by: Christophe Leroy +Reviewed-by: Naveen N Rao +Acked-by: Paul E. McKenney +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240513100248.110535-1-puranjay@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/net/bpf_jit_comp32.c | 12 ++++++++++++ + arch/powerpc/net/bpf_jit_comp64.c | 12 ++++++++++++ + 2 files changed, 24 insertions(+) + +--- a/arch/powerpc/net/bpf_jit_comp32.c ++++ b/arch/powerpc/net/bpf_jit_comp32.c +@@ -814,6 +814,15 @@ int bpf_jit_build_body(struct bpf_prog * + + /* Get offset into TMP_REG */ + EMIT(PPC_RAW_LI(tmp_reg, off)); ++ /* ++ * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync' ++ * before and after the operation. ++ * ++ * This is a requirement in the Linux Kernel Memory Model. ++ * See __cmpxchg_u32() in asm/cmpxchg.h as an example. ++ */ ++ if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP)) ++ EMIT(PPC_RAW_SYNC()); + tmp_idx = ctx->idx * 4; + /* load value from memory into r0 */ + EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0)); +@@ -867,6 +876,9 @@ int bpf_jit_build_body(struct bpf_prog * + + /* For the BPF_FETCH variant, get old data into src_reg */ + if (imm & BPF_FETCH) { ++ /* Emit 'sync' to enforce full ordering */ ++ if (IS_ENABLED(CONFIG_SMP)) ++ EMIT(PPC_RAW_SYNC()); + EMIT(PPC_RAW_MR(ret_reg, ax_reg)); + if (!fp->aux->verifier_zext) + EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */ +--- a/arch/powerpc/net/bpf_jit_comp64.c ++++ b/arch/powerpc/net/bpf_jit_comp64.c +@@ -784,6 +784,15 @@ emit_clear: + + /* Get offset into TMP_REG_1 */ + EMIT(PPC_RAW_LI(tmp1_reg, off)); ++ /* ++ * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync' ++ * before and after the operation. ++ * ++ * This is a requirement in the Linux Kernel Memory Model. ++ * See __cmpxchg_u64() in asm/cmpxchg.h as an example. ++ */ ++ if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP)) ++ EMIT(PPC_RAW_SYNC()); + tmp_idx = ctx->idx * 4; + /* load value from memory into TMP_REG_2 */ + if (size == BPF_DW) +@@ -846,6 +855,9 @@ emit_clear: + PPC_BCC_SHORT(COND_NE, tmp_idx); + + if (imm & BPF_FETCH) { ++ /* Emit 'sync' to enforce full ordering */ ++ if (IS_ENABLED(CONFIG_SMP)) ++ EMIT(PPC_RAW_SYNC()); + EMIT(PPC_RAW_MR(ret_reg, _R0)); + /* + * Skip unnecessary zero-extension for 32-bit cmpxchg. diff --git a/queue-6.1/series b/queue-6.1/series index c5f6fcd7e5b..deda3fc9f1a 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -77,3 +77,9 @@ s390-ap-fix-crash-in-ap-internal-function-modify_bitmap.patch s390-cpacf-split-and-rework-cpacf-query-functions.patch s390-cpacf-make-use-of-invalid-opcode-produce-a-link-error.patch i3c-master-svc-fix-invalidate-ibi-type-and-miss-call-client-ibi-handler.patch +edac-igen6-convert-pcibios_-return-codes-to-errnos.patch +nfs-fix-undefined-behavior-in-nfs_block_bits.patch +nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch +btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch +powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch +smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch diff --git a/queue-6.1/smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch b/queue-6.1/smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch new file mode 100644 index 00000000000..95a21d4e02a --- /dev/null +++ b/queue-6.1/smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch @@ -0,0 +1,34 @@ +From 02c418774f76a0a36a6195c9dbf8971eb4130a15 Mon Sep 17 00:00:00 2001 +From: Enzo Matsumiya +Date: Thu, 6 Jun 2024 13:13:13 -0300 +Subject: smb: client: fix deadlock in smb2_find_smb_tcon() + +From: Enzo Matsumiya + +commit 02c418774f76a0a36a6195c9dbf8971eb4130a15 upstream. + +Unlock cifs_tcp_ses_lock before calling cifs_put_smb_ses() to avoid such +deadlock. + +Cc: stable@vger.kernel.org +Signed-off-by: Enzo Matsumiya +Reviewed-by: Shyam Prasad N +Reviewed-by: Paulo Alcantara (Red Hat) +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/smb2transport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/smb/client/smb2transport.c ++++ b/fs/smb/client/smb2transport.c +@@ -213,8 +213,8 @@ smb2_find_smb_tcon(struct TCP_Server_Inf + } + tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); + if (!tcon) { +- cifs_put_smb_ses(ses); + spin_unlock(&cifs_tcp_ses_lock); ++ cifs_put_smb_ses(ses); + return NULL; + } + spin_unlock(&cifs_tcp_ses_lock);