]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Jun 2024 11:02:55 +0000 (13:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Jun 2024 11:02:55 +0000 (13:02 +0200)
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

queue-6.1/btrfs-fix-crash-on-racing-fsync-and-size-extending-write-into-prealloc.patch [new file with mode: 0644]
queue-6.1/edac-igen6-convert-pcibios_-return-codes-to-errnos.patch [new file with mode: 0644]
queue-6.1/nfs-fix-read_plus-when-server-doesn-t-support-op_read_plus.patch [new file with mode: 0644]
queue-6.1/nfs-fix-undefined-behavior-in-nfs_block_bits.patch [new file with mode: 0644]
queue-6.1/powerpc-bpf-enforce-full-ordering-for-atomic-operations-with-bpf_fetch.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/smb-client-fix-deadlock-in-smb2_find_smb_tcon.patch [new file with mode: 0644]

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 (file)
index 0000000..314dfc6
--- /dev/null
@@ -0,0 +1,218 @@
+From 9d274c19a71b3a276949933859610721a453946b Mon Sep 17 00:00:00 2001
+From: Omar Sandoval <osandov@fb.com>
+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 <osandov@fb.com>
+
+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 <fdmanana@suse.com>
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..475d778
--- /dev/null
@@ -0,0 +1,51 @@
+From f8367a74aebf88dc8b58a0db6a6c90b4cb8fc9d3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
+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 <ilpo.jarvinen@linux.intel.com>
+
+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 <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+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 <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..dec2c9b
--- /dev/null
@@ -0,0 +1,41 @@
+From f06d1b10cb016d5aaecdb1804fefca025387bd10 Mon Sep 17 00:00:00 2001
+From: Anna Schumaker <Anna.Schumaker@Netapp.com>
+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 <Anna.Schumaker@Netapp.com>
+
+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 <kolga@netapp.com>
+Fixes: c567552612ec ("NFS: Add READ_PLUS data segment support")
+Cc: stable@vger.kernel.org # v5.10+
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..eaaa8b5
--- /dev/null
@@ -0,0 +1,38 @@
+From 3c0a2e0b0ae661457c8505fecc7be5501aa7a715 Mon Sep 17 00:00:00 2001
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+Date: Fri, 10 May 2024 23:24:04 +0300
+Subject: nfs: fix undefined behavior in nfs_block_bits()
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+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 <s.shtylyov@omp.ru>
+Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..df00117
--- /dev/null
@@ -0,0 +1,138 @@
+From b1e7cee96127468c2483cf10c2899c9b5cf79bf8 Mon Sep 17 00:00:00 2001
+From: Puranjay Mohan <puranjay@kernel.org>
+Date: Mon, 13 May 2024 10:02:48 +0000
+Subject: powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH
+
+From: Puranjay Mohan <puranjay@kernel.org>
+
+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 <puranjay@kernel.org>
+Reviewed-by: Christophe Leroy <christophe.leroy@csgroup.eu>
+Reviewed-by: Naveen N Rao <naveen@kernel.org>
+Acked-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://msgid.link/20240513100248.110535-1-puranjay@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.
index c5f6fcd7e5b4a8315aee631269a97b776f5e641b..deda3fc9f1a21cf9ffe6609bb2ec1acd34c1165d 100644 (file)
@@ -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 (file)
index 0000000..95a21d4
--- /dev/null
@@ -0,0 +1,34 @@
+From 02c418774f76a0a36a6195c9dbf8971eb4130a15 Mon Sep 17 00:00:00 2001
+From: Enzo Matsumiya <ematsumiya@suse.de>
+Date: Thu, 6 Jun 2024 13:13:13 -0300
+Subject: smb: client: fix deadlock in smb2_find_smb_tcon()
+
+From: Enzo Matsumiya <ematsumiya@suse.de>
+
+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 <ematsumiya@suse.de>
+Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);