]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jul 2018 10:43:26 +0000 (12:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jul 2018 10:43:26 +0000 (12:43 +0200)
added patches:
bcm63xx_enet-correct-clock-usage.patch
bcm63xx_enet-do-not-write-to-random-dma-channel-on-bcm6345.patch
btrfs-fix-duplicate-extents-after-fsync-of-file-with-prealloc-extents.patch
cpufreq-cppc-set-platform-specific-transition_delay_us.patch
crypto-crypto4xx-fix-crypto4xx_build_pdr-crypto4xx_build_sdr-leak.patch
crypto-crypto4xx-remove-bad-list_del.patch
ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_block.patch
ocfs2-subsystem.su_mutex-is-required-while-accessing-the-item-ci_parent.patch
pci-exynos-fix-a-potential-init_clk_resources-null-pointer-dereference.patch
xprtrdma-fix-corner-cases-when-handling-device-removal.patch

queue-4.14/bcm63xx_enet-correct-clock-usage.patch [new file with mode: 0644]
queue-4.14/bcm63xx_enet-do-not-write-to-random-dma-channel-on-bcm6345.patch [new file with mode: 0644]
queue-4.14/btrfs-fix-duplicate-extents-after-fsync-of-file-with-prealloc-extents.patch [new file with mode: 0644]
queue-4.14/cpufreq-cppc-set-platform-specific-transition_delay_us.patch [new file with mode: 0644]
queue-4.14/crypto-crypto4xx-fix-crypto4xx_build_pdr-crypto4xx_build_sdr-leak.patch [new file with mode: 0644]
queue-4.14/crypto-crypto4xx-remove-bad-list_del.patch [new file with mode: 0644]
queue-4.14/ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_block.patch [new file with mode: 0644]
queue-4.14/ocfs2-subsystem.su_mutex-is-required-while-accessing-the-item-ci_parent.patch [new file with mode: 0644]
queue-4.14/pci-exynos-fix-a-potential-init_clk_resources-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/xprtrdma-fix-corner-cases-when-handling-device-removal.patch [new file with mode: 0644]

diff --git a/queue-4.14/bcm63xx_enet-correct-clock-usage.patch b/queue-4.14/bcm63xx_enet-correct-clock-usage.patch
new file mode 100644 (file)
index 0000000..4cb9889
--- /dev/null
@@ -0,0 +1,109 @@
+From 9c86b846ce02f7e35d7234cf090b80553eba5389 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski@gmail.com>
+Date: Sun, 1 Oct 2017 13:02:15 +0200
+Subject: bcm63xx_enet: correct clock usage
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+commit 9c86b846ce02f7e35d7234cf090b80553eba5389 upstream.
+
+Check the return code of prepare_enable and change one last instance of
+enable only to prepare_enable. Also properly disable and release the
+clock in error paths and on remove for enetsw.
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/bcm63xx_enet.c |   31 ++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+@@ -1773,7 +1773,9 @@ static int bcm_enet_probe(struct platfor
+               ret = PTR_ERR(priv->mac_clk);
+               goto out;
+       }
+-      clk_prepare_enable(priv->mac_clk);
++      ret = clk_prepare_enable(priv->mac_clk);
++      if (ret)
++              goto out_put_clk_mac;
+       /* initialize default and fetch platform data */
+       priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+@@ -1805,9 +1807,11 @@ static int bcm_enet_probe(struct platfor
+               if (IS_ERR(priv->phy_clk)) {
+                       ret = PTR_ERR(priv->phy_clk);
+                       priv->phy_clk = NULL;
+-                      goto out_put_clk_mac;
++                      goto out_disable_clk_mac;
+               }
+-              clk_prepare_enable(priv->phy_clk);
++              ret = clk_prepare_enable(priv->phy_clk);
++              if (ret)
++                      goto out_put_clk_phy;
+       }
+       /* do minimal hardware init to be able to probe mii bus */
+@@ -1901,13 +1905,16 @@ out_free_mdio:
+ out_uninit_hw:
+       /* turn off mdc clock */
+       enet_writel(priv, 0, ENET_MIISC_REG);
+-      if (priv->phy_clk) {
++      if (priv->phy_clk)
+               clk_disable_unprepare(priv->phy_clk);
++
++out_put_clk_phy:
++      if (priv->phy_clk)
+               clk_put(priv->phy_clk);
+-      }
+-out_put_clk_mac:
++out_disable_clk_mac:
+       clk_disable_unprepare(priv->mac_clk);
++out_put_clk_mac:
+       clk_put(priv->mac_clk);
+ out:
+       free_netdev(dev);
+@@ -2752,7 +2759,9 @@ static int bcm_enetsw_probe(struct platf
+               ret = PTR_ERR(priv->mac_clk);
+               goto out_unmap;
+       }
+-      clk_enable(priv->mac_clk);
++      ret = clk_prepare_enable(priv->mac_clk);
++      if (ret)
++              goto out_put_clk;
+       priv->rx_chan = 0;
+       priv->tx_chan = 1;
+@@ -2773,7 +2782,7 @@ static int bcm_enetsw_probe(struct platf
+       ret = register_netdev(dev);
+       if (ret)
+-              goto out_put_clk;
++              goto out_disable_clk;
+       netif_carrier_off(dev);
+       platform_set_drvdata(pdev, dev);
+@@ -2782,6 +2791,9 @@ static int bcm_enetsw_probe(struct platf
+       return 0;
++out_disable_clk:
++      clk_disable_unprepare(priv->mac_clk);
++
+ out_put_clk:
+       clk_put(priv->mac_clk);
+@@ -2813,6 +2825,9 @@ static int bcm_enetsw_remove(struct plat
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, resource_size(res));
++      clk_disable_unprepare(priv->mac_clk);
++      clk_put(priv->mac_clk);
++
+       free_netdev(dev);
+       return 0;
+ }
diff --git a/queue-4.14/bcm63xx_enet-do-not-write-to-random-dma-channel-on-bcm6345.patch b/queue-4.14/bcm63xx_enet-do-not-write-to-random-dma-channel-on-bcm6345.patch
new file mode 100644 (file)
index 0000000..792dd7b
--- /dev/null
@@ -0,0 +1,36 @@
+From d6213c1f2ad54a964b77471690264ed685718928 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jonas.gorski@gmail.com>
+Date: Sun, 1 Oct 2017 13:02:16 +0200
+Subject: bcm63xx_enet: do not write to random DMA channel on BCM6345
+
+From: Jonas Gorski <jonas.gorski@gmail.com>
+
+commit d6213c1f2ad54a964b77471690264ed685718928 upstream.
+
+The DMA controller regs actually point to DMA channel 0, so the write to
+ENETDMA_CFG_REG will actually modify a random DMA channel.
+
+Since DMA controller registers do not exist on BCM6345, guard the write
+with the usual check for dma_has_sram.
+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/bcm63xx_enet.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+@@ -1062,7 +1062,8 @@ static int bcm_enet_open(struct net_devi
+       val = enet_readl(priv, ENET_CTL_REG);
+       val |= ENET_CTL_ENABLE_MASK;
+       enet_writel(priv, val, ENET_CTL_REG);
+-      enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
++      if (priv->dma_has_sram)
++              enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+       enet_dmac_writel(priv, priv->dma_chan_en_mask,
+                        ENETDMAC_CHANCFG, priv->rx_chan);
diff --git a/queue-4.14/btrfs-fix-duplicate-extents-after-fsync-of-file-with-prealloc-extents.patch b/queue-4.14/btrfs-fix-duplicate-extents-after-fsync-of-file-with-prealloc-extents.patch
new file mode 100644 (file)
index 0000000..7afacaa
--- /dev/null
@@ -0,0 +1,390 @@
+From 31d11b83b96faaee4bb514d375a09489117c3e8d Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 9 May 2018 16:01:46 +0100
+Subject: Btrfs: fix duplicate extents after fsync of file with prealloc extents
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 31d11b83b96faaee4bb514d375a09489117c3e8d upstream.
+
+In commit 471d557afed1 ("Btrfs: fix loss of prealloc extents past i_size
+after fsync log replay"), on fsync,  we started to always log all prealloc
+extents beyond an inode's i_size in order to avoid losing them after a
+power failure. However under some cases this can lead to the log replay
+code to create duplicate extent items, with different lengths, in the
+extent tree. That happens because, as of that commit, we can now log
+extent items based on extent maps that are not on the "modified" list
+of extent maps of the inode's extent map tree. Logging extent items based
+on extent maps is used during the fast fsync path to save time and for
+this to work reliably it requires that the extent maps are not merged
+with other adjacent extent maps - having the extent maps in the list
+of modified extents gives such guarantee.
+
+Consider the following example, captured during a long run of fsstress,
+which illustrates this problem.
+
+We have inode 271, in the filesystem tree (root 5), for which all of the
+following operations and discussion apply to.
+
+A buffered write starts at offset 312391 with a length of 933471 bytes
+(end offset at 1245862). At this point we have, for this inode, the
+following extent maps with the their field values:
+
+em A, start 0, orig_start 0, len 40960, block_start 18446744073709551613,
+      block_len 0, orig_block_len 0
+em B, start 40960, orig_start 40960, len 376832, block_start 1106399232,
+      block_len 376832, orig_block_len 376832
+em C, start 417792, orig_start 417792, len 782336, block_start
+      18446744073709551613, block_len 0, orig_block_len 0
+em D, start 1200128, orig_start 1200128, len 835584, block_start
+      1106776064, block_len 835584, orig_block_len 835584
+em E, start 2035712, orig_start 2035712, len 245760, block_start
+      1107611648, block_len 245760, orig_block_len 245760
+
+Extent map A corresponds to a hole and extent maps D and E correspond to
+preallocated extents.
+
+Extent map D ends where extent map E begins (1106776064 + 835584 =
+1107611648), but these extent maps were not merged because they are in
+the inode's list of modified extent maps.
+
+An fsync against this inode is made, which triggers the fast path
+(BTRFS_INODE_NEEDS_FULL_SYNC is not set). This fsync triggers writeback
+of the data previously written using buffered IO, and when the respective
+ordered extent finishes, btrfs_drop_extents() is called against the
+(aligned) range 311296..1249279. This causes a split of extent map D at
+btrfs_drop_extent_cache(), replacing extent map D with a new extent map
+D', also added to the list of modified extents,  with the following
+values:
+
+em D', start 1249280, orig_start of 1200128,
+       block_start 1106825216 (= 1106776064 + 1249280 - 1200128),
+       orig_block_len 835584,
+       block_len 786432 (835584 - (1249280 - 1200128))
+
+Then, during the fast fsync, btrfs_log_changed_extents() is called and
+extent maps D' and E are removed from the list of modified extents. The
+flag EXTENT_FLAG_LOGGING is also set on them. After the extents are logged
+clear_em_logging() is called on each of them, and that makes extent map E
+to be merged with extent map D' (try_merge_map()), resulting in D' being
+deleted and E adjusted to:
+
+em E, start 1249280, orig_start 1200128, len 1032192,
+      block_start 1106825216, block_len 1032192,
+      orig_block_len 245760
+
+A direct IO write at offset 1847296 and length of 360448 bytes (end offset
+at 2207744) starts, and at that moment the following extent maps exist for
+our inode:
+
+em A, start 0, orig_start 0, len 40960, block_start 18446744073709551613,
+      block_len 0, orig_block_len 0
+em B, start 40960, orig_start 40960, len 270336, block_start 1106399232,
+      block_len 270336, orig_block_len 376832
+em C, start 311296, orig_start 311296, len 937984, block_start 1112842240,
+      block_len 937984, orig_block_len 937984
+em E (prealloc), start 1249280, orig_start 1200128, len 1032192,
+      block_start 1106825216, block_len 1032192, orig_block_len 245760
+
+The dio write results in drop_extent_cache() being called twice. The first
+time for a range that starts at offset 1847296 and ends at offset 2035711
+(length of 188416), which results in a double split of extent map E,
+replacing it with two new extent maps:
+
+em F, start 1249280, orig_start 1200128, block_start 1106825216,
+      block_len 598016, orig_block_len 598016
+em G, start 2035712, orig_start 1200128, block_start 1107611648,
+      block_len 245760, orig_block_len 1032192
+
+It also creates a new extent map that represents a part of the requested
+IO (through create_io_em()):
+
+em H, start 1847296, len 188416, block_start 1107423232, block_len 188416
+
+The second call to drop_extent_cache() has a range with a start offset of
+2035712 and end offset of 2207743 (length of 172032). This leads to
+replacing extent map G with a new extent map I with the following values:
+
+em I, start 2207744, orig_start 1200128, block_start 1107783680,
+      block_len 73728, orig_block_len 1032192
+
+It also creates a new extent map that represents the second part of the
+requested IO (through create_io_em()):
+
+em J, start 2035712, len 172032, block_start 1107611648, block_len 172032
+
+The dio write set the inode's i_size to 2207744 bytes.
+
+After the dio write the inode has the following extent maps:
+
+em A, start 0, orig_start 0, len 40960, block_start 18446744073709551613,
+      block_len 0, orig_block_len 0
+em B, start 40960, orig_start 40960, len 270336, block_start 1106399232,
+      block_len 270336, orig_block_len 376832
+em C, start 311296, orig_start 311296, len 937984, block_start 1112842240,
+      block_len 937984, orig_block_len 937984
+em F, start 1249280, orig_start 1200128, len 598016,
+      block_start 1106825216, block_len 598016, orig_block_len 598016
+em H, start 1847296, orig_start 1200128, len 188416,
+      block_start 1107423232, block_len 188416, orig_block_len 835584
+em J, start 2035712, orig_start 2035712, len 172032,
+      block_start 1107611648, block_len 172032, orig_block_len 245760
+em I, start 2207744, orig_start 1200128, len 73728,
+      block_start 1107783680, block_len 73728, orig_block_len 1032192
+
+Now do some change to the file, like adding a xattr for example and then
+fsync it again. This triggers a fast fsync path, and as of commit
+471d557afed1 ("Btrfs: fix loss of prealloc extents past i_size after fsync
+log replay"), we use the extent map I to log a file extent item because
+it's a prealloc extent and it starts at an offset matching the inode's
+i_size. However when we log it, we create a file extent item with a value
+for the disk byte location that is wrong, as can be seen from the
+following output of "btrfs inspect-internal dump-tree":
+
+ item 1 key (271 EXTENT_DATA 2207744) itemoff 3782 itemsize 53
+     generation 22 type 2 (prealloc)
+     prealloc data disk byte 1106776064 nr 1032192
+     prealloc data offset 1007616 nr 73728
+
+Here the disk byte value corresponds to calculation based on some fields
+from the extent map I:
+
+  1106776064 = block_start (1107783680) - 1007616 (extent_offset)
+  extent_offset = 2207744 (start) - 1200128 (orig_start) = 1007616
+
+The disk byte value of 1106776064 clashes with disk byte values of the
+file extent items at offsets 1249280 and 1847296 in the fs tree:
+
+        item 6 key (271 EXTENT_DATA 1249280) itemoff 3568 itemsize 53
+                generation 20 type 2 (prealloc)
+                prealloc data disk byte 1106776064 nr 835584
+                prealloc data offset 49152 nr 598016
+        item 7 key (271 EXTENT_DATA 1847296) itemoff 3515 itemsize 53
+                generation 20 type 1 (regular)
+                extent data disk byte 1106776064 nr 835584
+                extent data offset 647168 nr 188416 ram 835584
+                extent compression 0 (none)
+        item 8 key (271 EXTENT_DATA 2035712) itemoff 3462 itemsize 53
+                generation 20 type 1 (regular)
+                extent data disk byte 1107611648 nr 245760
+                extent data offset 0 nr 172032 ram 245760
+                extent compression 0 (none)
+        item 9 key (271 EXTENT_DATA 2207744) itemoff 3409 itemsize 53
+                generation 20 type 2 (prealloc)
+                prealloc data disk byte 1107611648 nr 245760
+                prealloc data offset 172032 nr 73728
+
+Instead of the disk byte value of 1106776064, the value of 1107611648
+should have been logged. Also the data offset value should have been
+172032 and not 1007616.
+After a log replay we end up getting two extent items in the extent tree
+with different lengths, one of 835584, which is correct and existed
+before the log replay, and another one of 1032192 which is wrong and is
+based on the logged file extent item:
+
+ item 12 key (1106776064 EXTENT_ITEM 835584) itemoff 3406 itemsize 53
+    refs 2 gen 15 flags DATA
+    extent data backref root 5 objectid 271 offset 1200128 count 2
+ item 13 key (1106776064 EXTENT_ITEM 1032192) itemoff 3353 itemsize 53
+    refs 1 gen 22 flags DATA
+    extent data backref root 5 objectid 271 offset 1200128 count 1
+
+Obviously this leads to many problems and a filesystem check reports many
+errors:
+
+ (...)
+ checking extents
+ Extent back ref already exists for 1106776064 parent 0 root 5 owner 271 offset 1200128 num_refs 1
+ extent item 1106776064 has multiple extent items
+ ref mismatch on [1106776064 835584] extent item 2, found 3
+ Incorrect local backref count on 1106776064 root 5 owner 271 offset 1200128 found 2 wanted 1 back 0x55b1d0ad7680
+ Backref 1106776064 root 5 owner 271 offset 1200128 num_refs 0 not found in extent tree
+ Incorrect local backref count on 1106776064 root 5 owner 271 offset 1200128 found 1 wanted 0 back 0x55b1d0ad4e70
+ Backref bytes do not match extent backref, bytenr=1106776064, ref bytes=835584, backref bytes=1032192
+ backpointer mismatch on [1106776064 835584]
+ checking free space cache
+ block group 1103101952 has wrong amount of free space
+ failed to load free space cache for block group 1103101952
+ checking fs roots
+ (...)
+
+So fix this by logging the prealloc extents beyond the inode's i_size
+based on searches in the subvolume tree instead of the extent maps.
+
+Fixes: 471d557afed1 ("Btrfs: fix loss of prealloc extents past i_size after fsync log replay")
+CC: stable@vger.kernel.org # 4.14+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/tree-log.c |  137 ++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 112 insertions(+), 25 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -4214,6 +4214,110 @@ static int log_one_extent(struct btrfs_t
+       return ret;
+ }
++/*
++ * Log all prealloc extents beyond the inode's i_size to make sure we do not
++ * lose them after doing a fast fsync and replaying the log. We scan the
++ * subvolume's root instead of iterating the inode's extent map tree because
++ * otherwise we can log incorrect extent items based on extent map conversion.
++ * That can happen due to the fact that extent maps are merged when they
++ * are not in the extent map tree's list of modified extents.
++ */
++static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans,
++                                    struct btrfs_inode *inode,
++                                    struct btrfs_path *path)
++{
++      struct btrfs_root *root = inode->root;
++      struct btrfs_key key;
++      const u64 i_size = i_size_read(&inode->vfs_inode);
++      const u64 ino = btrfs_ino(inode);
++      struct btrfs_path *dst_path = NULL;
++      u64 last_extent = (u64)-1;
++      int ins_nr = 0;
++      int start_slot;
++      int ret;
++
++      if (!(inode->flags & BTRFS_INODE_PREALLOC))
++              return 0;
++
++      key.objectid = ino;
++      key.type = BTRFS_EXTENT_DATA_KEY;
++      key.offset = i_size;
++      ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
++      if (ret < 0)
++              goto out;
++
++      while (true) {
++              struct extent_buffer *leaf = path->nodes[0];
++              int slot = path->slots[0];
++
++              if (slot >= btrfs_header_nritems(leaf)) {
++                      if (ins_nr > 0) {
++                              ret = copy_items(trans, inode, dst_path, path,
++                                               &last_extent, start_slot,
++                                               ins_nr, 1, 0);
++                              if (ret < 0)
++                                      goto out;
++                              ins_nr = 0;
++                      }
++                      ret = btrfs_next_leaf(root, path);
++                      if (ret < 0)
++                              goto out;
++                      if (ret > 0) {
++                              ret = 0;
++                              break;
++                      }
++                      continue;
++              }
++
++              btrfs_item_key_to_cpu(leaf, &key, slot);
++              if (key.objectid > ino)
++                      break;
++              if (WARN_ON_ONCE(key.objectid < ino) ||
++                  key.type < BTRFS_EXTENT_DATA_KEY ||
++                  key.offset < i_size) {
++                      path->slots[0]++;
++                      continue;
++              }
++              if (last_extent == (u64)-1) {
++                      last_extent = key.offset;
++                      /*
++                       * Avoid logging extent items logged in past fsync calls
++                       * and leading to duplicate keys in the log tree.
++                       */
++                      do {
++                              ret = btrfs_truncate_inode_items(trans,
++                                                       root->log_root,
++                                                       &inode->vfs_inode,
++                                                       i_size,
++                                                       BTRFS_EXTENT_DATA_KEY);
++                      } while (ret == -EAGAIN);
++                      if (ret)
++                              goto out;
++              }
++              if (ins_nr == 0)
++                      start_slot = slot;
++              ins_nr++;
++              path->slots[0]++;
++              if (!dst_path) {
++                      dst_path = btrfs_alloc_path();
++                      if (!dst_path) {
++                              ret = -ENOMEM;
++                              goto out;
++                      }
++              }
++      }
++      if (ins_nr > 0) {
++              ret = copy_items(trans, inode, dst_path, path, &last_extent,
++                               start_slot, ins_nr, 1, 0);
++              if (ret > 0)
++                      ret = 0;
++      }
++out:
++      btrfs_release_path(path);
++      btrfs_free_path(dst_path);
++      return ret;
++}
++
+ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
+                                    struct btrfs_root *root,
+                                    struct btrfs_inode *inode,
+@@ -4256,6 +4360,11 @@ static int btrfs_log_changed_extents(str
+               if (em->generation <= test_gen)
+                       continue;
++              /* We log prealloc extents beyond eof later. */
++              if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) &&
++                  em->start >= i_size_read(&inode->vfs_inode))
++                      continue;
++
+               if (em->start < logged_start)
+                       logged_start = em->start;
+               if ((em->start + em->len - 1) > logged_end)
+@@ -4268,31 +4377,6 @@ static int btrfs_log_changed_extents(str
+               num++;
+       }
+-      /*
+-       * Add all prealloc extents beyond the inode's i_size to make sure we
+-       * don't lose them after doing a fast fsync and replaying the log.
+-       */
+-      if (inode->flags & BTRFS_INODE_PREALLOC) {
+-              struct rb_node *node;
+-
+-              for (node = rb_last(&tree->map); node; node = rb_prev(node)) {
+-                      em = rb_entry(node, struct extent_map, rb_node);
+-                      if (em->start < i_size_read(&inode->vfs_inode))
+-                              break;
+-                      if (!list_empty(&em->list))
+-                              continue;
+-                      /* Same as above loop. */
+-                      if (++num > 32768) {
+-                              list_del_init(&tree->modified_extents);
+-                              ret = -EFBIG;
+-                              goto process;
+-                      }
+-                      refcount_inc(&em->refs);
+-                      set_bit(EXTENT_FLAG_LOGGING, &em->flags);
+-                      list_add_tail(&em->list, &extents);
+-              }
+-      }
+-
+       list_sort(NULL, &extents, extent_cmp);
+       btrfs_get_logged_extents(inode, logged_list, logged_start, logged_end);
+       /*
+@@ -4337,6 +4421,9 @@ process:
+       up_write(&inode->dio_sem);
+       btrfs_release_path(path);
++      if (!ret)
++              ret = btrfs_log_prealloc_extents(trans, inode, path);
++
+       return ret;
+ }
diff --git a/queue-4.14/cpufreq-cppc-set-platform-specific-transition_delay_us.patch b/queue-4.14/cpufreq-cppc-set-platform-specific-transition_delay_us.patch
new file mode 100644 (file)
index 0000000..06009f3
--- /dev/null
@@ -0,0 +1,108 @@
+From d4f3388afd488ed15368fa7413b8bd6d1f98bb1d Mon Sep 17 00:00:00 2001
+From: Prashanth Prakash <pprakash@codeaurora.org>
+Date: Fri, 27 Apr 2018 11:35:27 -0600
+Subject: cpufreq / CPPC: Set platform specific transition_delay_us
+
+From: Prashanth Prakash <pprakash@codeaurora.org>
+
+commit d4f3388afd488ed15368fa7413b8bd6d1f98bb1d upstream.
+
+Add support to specify platform specific transition_delay_us instead
+of using the transition delay derived from PCC.
+
+With commit 3d41386d556d (cpufreq: CPPC: Use transition_delay_us
+depending transition_latency) we are setting transition_delay_us
+directly and not applying the LATENCY_MULTIPLIER. Because of that,
+on Qualcomm Centriq we can end up with a very high rate of frequency
+change requests when using the schedutil governor (default
+rate_limit_us=10 compared to an earlier value of 10000).
+
+The PCC subspace describes the rate at which the platform can accept
+commands on the CPPC's PCC channel. This includes read and write
+command on the PCC channel that can be used for reasons other than
+frequency transitions. Moreover the same PCC subspace can be used by
+multiple freq domains and deriving transition_delay_us from it as we
+do now can be sub-optimal.
+
+Moreover if a platform does not use PCC for desired_perf register then
+there is no way to compute the transition latency or the delay_us.
+
+CPPC does not have a standard defined mechanism to get the transition
+rate or the latency at the moment.
+
+Given the above limitations, it is simpler to have a platform specific
+transition_delay_us and rely on PCC derived value only if a platform
+specific value is not available.
+
+Signed-off-by: Prashanth Prakash <pprakash@codeaurora.org>
+Cc: 4.14+ <stable@vger.kernel.org> # 4.14+
+Fixes: 3d41386d556d (cpufreq: CPPC: Use transition_delay_us depending transition_latency)
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/cppc_cpufreq.c |   46 +++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 44 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/cppc_cpufreq.c
++++ b/drivers/cpufreq/cppc_cpufreq.c
+@@ -126,6 +126,49 @@ static void cppc_cpufreq_stop_cpu(struct
+                               cpu->perf_caps.lowest_perf, cpu_num, ret);
+ }
++/*
++ * The PCC subspace describes the rate at which platform can accept commands
++ * on the shared PCC channel (including READs which do not count towards freq
++ * trasition requests), so ideally we need to use the PCC values as a fallback
++ * if we don't have a platform specific transition_delay_us
++ */
++#ifdef CONFIG_ARM64
++#include <asm/cputype.h>
++
++static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
++{
++      unsigned long implementor = read_cpuid_implementor();
++      unsigned long part_num = read_cpuid_part_number();
++      unsigned int delay_us = 0;
++
++      switch (implementor) {
++      case ARM_CPU_IMP_QCOM:
++              switch (part_num) {
++              case QCOM_CPU_PART_FALKOR_V1:
++              case QCOM_CPU_PART_FALKOR:
++                      delay_us = 10000;
++                      break;
++              default:
++                      delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
++                      break;
++              }
++              break;
++      default:
++              delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
++              break;
++      }
++
++      return delay_us;
++}
++
++#else
++
++static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
++{
++      return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
++}
++#endif
++
+ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+ {
+       struct cppc_cpudata *cpu;
+@@ -163,8 +206,7 @@ static int cppc_cpufreq_cpu_init(struct
+       policy->cpuinfo.max_freq = cppc_dmi_max_khz;
+       policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num);
+-      policy->transition_delay_us = cppc_get_transition_latency(cpu_num) /
+-              NSEC_PER_USEC;
++      policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
+       policy->shared_type = cpu->shared_type;
+       if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
diff --git a/queue-4.14/crypto-crypto4xx-fix-crypto4xx_build_pdr-crypto4xx_build_sdr-leak.patch b/queue-4.14/crypto-crypto4xx-fix-crypto4xx_build_pdr-crypto4xx_build_sdr-leak.patch
new file mode 100644 (file)
index 0000000..f9ec80e
--- /dev/null
@@ -0,0 +1,90 @@
+From 5d59ad6eea82ef8df92b4109615a0dde9d8093e9 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Fri, 25 Aug 2017 15:47:24 +0200
+Subject: crypto: crypto4xx - fix crypto4xx_build_pdr, crypto4xx_build_sdr leak
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit 5d59ad6eea82ef8df92b4109615a0dde9d8093e9 upstream.
+
+If one of the later memory allocations in rypto4xx_build_pdr()
+fails: dev->pdr (and/or) dev->pdr_uinfo wouldn't be freed.
+
+crypto4xx_build_sdr() has the same issue with dev->sdr.
+
+Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/amcc/crypto4xx_core.c |   17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -207,7 +207,7 @@ static u32 crypto4xx_build_pdr(struct cr
+                                 dev->pdr_pa);
+               return -ENOMEM;
+       }
+-      memset(dev->pdr, 0,  sizeof(struct ce_pd) * PPC4XX_NUM_PD);
++      memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD);
+       dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
+                                  256 * PPC4XX_NUM_PD,
+                                  &dev->shadow_sa_pool_pa,
+@@ -240,13 +240,15 @@ static u32 crypto4xx_build_pdr(struct cr
+ static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev)
+ {
+-      if (dev->pdr != NULL)
++      if (dev->pdr)
+               dma_free_coherent(dev->core_dev->device,
+                                 sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+                                 dev->pdr, dev->pdr_pa);
++
+       if (dev->shadow_sa_pool)
+               dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD,
+                                 dev->shadow_sa_pool, dev->shadow_sa_pool_pa);
++
+       if (dev->shadow_sr_pool)
+               dma_free_coherent(dev->core_dev->device,
+                       sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+@@ -416,12 +418,12 @@ static u32 crypto4xx_build_sdr(struct cr
+ static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev)
+ {
+-      if (dev->sdr != NULL)
++      if (dev->sdr)
+               dma_free_coherent(dev->core_dev->device,
+                                 sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+                                 dev->sdr, dev->sdr_pa);
+-      if (dev->scatter_buffer_va != NULL)
++      if (dev->scatter_buffer_va)
+               dma_free_coherent(dev->core_dev->device,
+                                 dev->scatter_buffer_size * PPC4XX_NUM_SD,
+                                 dev->scatter_buffer_va,
+@@ -1191,7 +1193,7 @@ static int crypto4xx_probe(struct platfo
+       rc = crypto4xx_build_gdr(core_dev->dev);
+       if (rc)
+-              goto err_build_gdr;
++              goto err_build_pdr;
+       rc = crypto4xx_build_sdr(core_dev->dev);
+       if (rc)
+@@ -1234,12 +1236,11 @@ err_iomap:
+ err_request_irq:
+       irq_dispose_mapping(core_dev->irq);
+       tasklet_kill(&core_dev->tasklet);
+-      crypto4xx_destroy_sdr(core_dev->dev);
+ err_build_sdr:
++      crypto4xx_destroy_sdr(core_dev->dev);
+       crypto4xx_destroy_gdr(core_dev->dev);
+-err_build_gdr:
+-      crypto4xx_destroy_pdr(core_dev->dev);
+ err_build_pdr:
++      crypto4xx_destroy_pdr(core_dev->dev);
+       kfree(core_dev->dev);
+ err_alloc_dev:
+       kfree(core_dev);
diff --git a/queue-4.14/crypto-crypto4xx-remove-bad-list_del.patch b/queue-4.14/crypto-crypto4xx-remove-bad-list_del.patch
new file mode 100644 (file)
index 0000000..92b21e7
--- /dev/null
@@ -0,0 +1,39 @@
+From a728a196d253530f17da5c86dc7dfbe58c5f7094 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Fri, 25 Aug 2017 15:47:14 +0200
+Subject: crypto: crypto4xx - remove bad list_del
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit a728a196d253530f17da5c86dc7dfbe58c5f7094 upstream.
+
+alg entries are only added to the list, after the registration
+was successful. If the registration failed, it was never added
+to the list in the first place.
+
+Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/amcc/crypto4xx_core.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/amcc/crypto4xx_core.c
++++ b/drivers/crypto/amcc/crypto4xx_core.c
+@@ -1033,12 +1033,10 @@ int crypto4xx_register_alg(struct crypto
+                       break;
+               }
+-              if (rc) {
+-                      list_del(&alg->entry);
++              if (rc)
+                       kfree(alg);
+-              } else {
++              else
+                       list_add_tail(&alg->entry, &sec_dev->alg_list);
+-              }
+       }
+       return 0;
diff --git a/queue-4.14/ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_block.patch b/queue-4.14/ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_block.patch
new file mode 100644 (file)
index 0000000..ee718f4
--- /dev/null
@@ -0,0 +1,122 @@
+From 3e4c56d41eef5595035872a2ec5a483f42e8917f Mon Sep 17 00:00:00 2001
+From: alex chen <alex.chen@huawei.com>
+Date: Wed, 15 Nov 2017 17:31:44 -0800
+Subject: ocfs2: ip_alloc_sem should be taken in ocfs2_get_block()
+
+From: alex chen <alex.chen@huawei.com>
+
+commit 3e4c56d41eef5595035872a2ec5a483f42e8917f upstream.
+
+ip_alloc_sem should be taken in ocfs2_get_block() when reading file in
+DIRECT mode to prevent concurrent access to extent tree with
+ocfs2_dio_end_io_write(), which may cause BUGON in the following
+situation:
+
+read file 'A'                                  end_io of writing file 'A'
+vfs_read
+ __vfs_read
+  ocfs2_file_read_iter
+   generic_file_read_iter
+    ocfs2_direct_IO
+     __blockdev_direct_IO
+      do_blockdev_direct_IO
+       do_direct_IO
+        get_more_blocks
+         ocfs2_get_block
+          ocfs2_extent_map_get_blocks
+           ocfs2_get_clusters
+            ocfs2_get_clusters_nocache()
+             ocfs2_search_extent_list
+              return the index of record which
+              contains the v_cluster, that is
+              v_cluster > rec[i]->e_cpos.
+                                                ocfs2_dio_end_io
+                                                 ocfs2_dio_end_io_write
+                                                  down_write(&oi->ip_alloc_sem);
+                                                  ocfs2_mark_extent_written
+                                                   ocfs2_change_extent_flag
+                                                    ocfs2_split_extent
+                                                     ...
+                                                 --> modify the rec[i]->e_cpos, resulting
+                                                     in v_cluster < rec[i]->e_cpos.
+             BUG_ON(v_cluster < le32_to_cpu(rec->e_cpos))
+
+[alex.chen@huawei.com: v3]
+  Link: http://lkml.kernel.org/r/59EF3614.6050008@huawei.com
+Link: http://lkml.kernel.org/r/59EF3614.6050008@huawei.com
+Fixes: c15471f79506 ("ocfs2: fix sparse file & data ordering issue in direct io")
+Signed-off-by: Alex Chen <alex.chen@huawei.com>
+Reviewed-by: Jun Piao <piaojun@huawei.com>
+Reviewed-by: Joseph Qi <jiangqi903@gmail.com>
+Reviewed-by: Gang He <ghe@suse.com>
+Acked-by: Changwei Ge <ge.changwei@h3c.com>
+Cc: Mark Fasheh <mfasheh@versity.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Salvatore Bonaccorso <carnil@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/aops.c |   26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -134,6 +134,19 @@ bail:
+       return err;
+ }
++static int ocfs2_lock_get_block(struct inode *inode, sector_t iblock,
++                  struct buffer_head *bh_result, int create)
++{
++      int ret = 0;
++      struct ocfs2_inode_info *oi = OCFS2_I(inode);
++
++      down_read(&oi->ip_alloc_sem);
++      ret = ocfs2_get_block(inode, iblock, bh_result, create);
++      up_read(&oi->ip_alloc_sem);
++
++      return ret;
++}
++
+ int ocfs2_get_block(struct inode *inode, sector_t iblock,
+                   struct buffer_head *bh_result, int create)
+ {
+@@ -2128,7 +2141,7 @@ static void ocfs2_dio_free_write_ctx(str
+  * called like this: dio->get_blocks(dio->inode, fs_startblk,
+  *                                    fs_count, map_bh, dio->rw == WRITE);
+  */
+-static int ocfs2_dio_get_block(struct inode *inode, sector_t iblock,
++static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock,
+                              struct buffer_head *bh_result, int create)
+ {
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+@@ -2154,12 +2167,9 @@ static int ocfs2_dio_get_block(struct in
+        * while file size will be changed.
+        */
+       if (pos + total_len <= i_size_read(inode)) {
+-              down_read(&oi->ip_alloc_sem);
+-              /* This is the fast path for re-write. */
+-              ret = ocfs2_get_block(inode, iblock, bh_result, create);
+-
+-              up_read(&oi->ip_alloc_sem);
++              /* This is the fast path for re-write. */
++              ret = ocfs2_lock_get_block(inode, iblock, bh_result, create);
+               if (buffer_mapped(bh_result) &&
+                   !buffer_new(bh_result) &&
+                   ret == 0)
+@@ -2424,9 +2434,9 @@ static ssize_t ocfs2_direct_IO(struct ki
+               return 0;
+       if (iov_iter_rw(iter) == READ)
+-              get_block = ocfs2_get_block;
++              get_block = ocfs2_lock_get_block;
+       else
+-              get_block = ocfs2_dio_get_block;
++              get_block = ocfs2_dio_wr_get_block;
+       return __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev,
+                                   iter, get_block,
diff --git a/queue-4.14/ocfs2-subsystem.su_mutex-is-required-while-accessing-the-item-ci_parent.patch b/queue-4.14/ocfs2-subsystem.su_mutex-is-required-while-accessing-the-item-ci_parent.patch
new file mode 100644 (file)
index 0000000..dcf54db
--- /dev/null
@@ -0,0 +1,208 @@
+From 853bc26a7ea39e354b9f8889ae7ad1492ffa28d2 Mon Sep 17 00:00:00 2001
+From: alex chen <alex.chen@huawei.com>
+Date: Wed, 15 Nov 2017 17:31:48 -0800
+Subject: ocfs2: subsystem.su_mutex is required while accessing the item->ci_parent
+
+From: alex chen <alex.chen@huawei.com>
+
+commit 853bc26a7ea39e354b9f8889ae7ad1492ffa28d2 upstream.
+
+The subsystem.su_mutex is required while accessing the item->ci_parent,
+otherwise, NULL pointer dereference to the item->ci_parent will be
+triggered in the following situation:
+
+add node                     delete node
+sys_write
+ vfs_write
+  configfs_write_file
+   o2nm_node_store
+    o2nm_node_local_write
+                             do_rmdir
+                              vfs_rmdir
+                               configfs_rmdir
+                                mutex_lock(&subsys->su_mutex);
+                                unlink_obj
+                                 item->ci_group = NULL;
+                                 item->ci_parent = NULL;
+        to_o2nm_cluster_from_node
+         node->nd_item.ci_parent->ci_parent
+         BUG since of NULL pointer dereference to nd_item.ci_parent
+
+Moreover, the o2nm_cluster also should be protected by the
+subsystem.su_mutex.
+
+[alex.chen@huawei.com: v2]
+  Link: http://lkml.kernel.org/r/59EEAA69.9080703@huawei.com
+Link: http://lkml.kernel.org/r/59E9B36A.10700@huawei.com
+Signed-off-by: Alex Chen <alex.chen@huawei.com>
+Reviewed-by: Jun Piao <piaojun@huawei.com>
+Reviewed-by: Joseph Qi <jiangqi903@gmail.com>
+Cc: Mark Fasheh <mfasheh@versity.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Salvatore Bonaccorso <carnil@debian.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ocfs2/cluster/nodemanager.c |   63 +++++++++++++++++++++++++++++++++++------
+ 1 file changed, 55 insertions(+), 8 deletions(-)
+
+--- a/fs/ocfs2/cluster/nodemanager.c
++++ b/fs/ocfs2/cluster/nodemanager.c
+@@ -40,6 +40,9 @@ char *o2nm_fence_method_desc[O2NM_FENCE_
+               "panic",        /* O2NM_FENCE_PANIC */
+ };
++static inline void o2nm_lock_subsystem(void);
++static inline void o2nm_unlock_subsystem(void);
++
+ struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
+ {
+       struct o2nm_node *node = NULL;
+@@ -181,7 +184,10 @@ static struct o2nm_cluster *to_o2nm_clus
+ {
+       /* through the first node_set .parent
+        * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
+-      return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
++      if (node->nd_item.ci_parent)
++              return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
++      else
++              return NULL;
+ }
+ enum {
+@@ -194,7 +200,7 @@ static ssize_t o2nm_node_num_store(struc
+                                  size_t count)
+ {
+       struct o2nm_node *node = to_o2nm_node(item);
+-      struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
++      struct o2nm_cluster *cluster;
+       unsigned long tmp;
+       char *p = (char *)page;
+       int ret = 0;
+@@ -214,6 +220,13 @@ static ssize_t o2nm_node_num_store(struc
+           !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+               return -EINVAL; /* XXX */
++      o2nm_lock_subsystem();
++      cluster = to_o2nm_cluster_from_node(node);
++      if (!cluster) {
++              o2nm_unlock_subsystem();
++              return -EINVAL;
++      }
++
+       write_lock(&cluster->cl_nodes_lock);
+       if (cluster->cl_nodes[tmp])
+               ret = -EEXIST;
+@@ -226,6 +239,8 @@ static ssize_t o2nm_node_num_store(struc
+               set_bit(tmp, cluster->cl_nodes_bitmap);
+       }
+       write_unlock(&cluster->cl_nodes_lock);
++      o2nm_unlock_subsystem();
++
+       if (ret)
+               return ret;
+@@ -269,7 +284,7 @@ static ssize_t o2nm_node_ipv4_address_st
+                                           size_t count)
+ {
+       struct o2nm_node *node = to_o2nm_node(item);
+-      struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
++      struct o2nm_cluster *cluster;
+       int ret, i;
+       struct rb_node **p, *parent;
+       unsigned int octets[4];
+@@ -286,6 +301,13 @@ static ssize_t o2nm_node_ipv4_address_st
+               be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
+       }
++      o2nm_lock_subsystem();
++      cluster = to_o2nm_cluster_from_node(node);
++      if (!cluster) {
++              o2nm_unlock_subsystem();
++              return -EINVAL;
++      }
++
+       ret = 0;
+       write_lock(&cluster->cl_nodes_lock);
+       if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
+@@ -298,6 +320,8 @@ static ssize_t o2nm_node_ipv4_address_st
+               rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
+       }
+       write_unlock(&cluster->cl_nodes_lock);
++      o2nm_unlock_subsystem();
++
+       if (ret)
+               return ret;
+@@ -315,7 +339,7 @@ static ssize_t o2nm_node_local_store(str
+                                    size_t count)
+ {
+       struct o2nm_node *node = to_o2nm_node(item);
+-      struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
++      struct o2nm_cluster *cluster;
+       unsigned long tmp;
+       char *p = (char *)page;
+       ssize_t ret;
+@@ -333,17 +357,26 @@ static ssize_t o2nm_node_local_store(str
+           !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+               return -EINVAL; /* XXX */
++      o2nm_lock_subsystem();
++      cluster = to_o2nm_cluster_from_node(node);
++      if (!cluster) {
++              ret = -EINVAL;
++              goto out;
++      }
++
+       /* the only failure case is trying to set a new local node
+        * when a different one is already set */
+       if (tmp && tmp == cluster->cl_has_local &&
+-          cluster->cl_local_node != node->nd_num)
+-              return -EBUSY;
++          cluster->cl_local_node != node->nd_num) {
++              ret = -EBUSY;
++              goto out;
++      }
+       /* bring up the rx thread if we're setting the new local node. */
+       if (tmp && !cluster->cl_has_local) {
+               ret = o2net_start_listening(node);
+               if (ret)
+-                      return ret;
++                      goto out;
+       }
+       if (!tmp && cluster->cl_has_local &&
+@@ -358,7 +391,11 @@ static ssize_t o2nm_node_local_store(str
+               cluster->cl_local_node = node->nd_num;
+       }
+-      return count;
++      ret = count;
++
++out:
++      o2nm_unlock_subsystem();
++      return ret;
+ }
+ CONFIGFS_ATTR(o2nm_node_, num);
+@@ -738,6 +775,16 @@ static struct o2nm_cluster_group o2nm_cl
+       },
+ };
++static inline void o2nm_lock_subsystem(void)
++{
++      mutex_lock(&o2nm_cluster_group.cs_subsys.su_mutex);
++}
++
++static inline void o2nm_unlock_subsystem(void)
++{
++      mutex_unlock(&o2nm_cluster_group.cs_subsys.su_mutex);
++}
++
+ int o2nm_depend_item(struct config_item *item)
+ {
+       return configfs_depend_item(&o2nm_cluster_group.cs_subsys, item);
diff --git a/queue-4.14/pci-exynos-fix-a-potential-init_clk_resources-null-pointer-dereference.patch b/queue-4.14/pci-exynos-fix-a-potential-init_clk_resources-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..c71ddd9
--- /dev/null
@@ -0,0 +1,37 @@
+From b5d6bc90c9129279d363ccbc02ad11e7b657c0b4 Mon Sep 17 00:00:00 2001
+From: Jaehoon Chung <jh80.chung@samsung.com>
+Date: Mon, 22 Jan 2018 11:28:54 +0900
+Subject: PCI: exynos: Fix a potential init_clk_resources NULL pointer dereference
+
+From: Jaehoon Chung <jh80.chung@samsung.com>
+
+commit b5d6bc90c9129279d363ccbc02ad11e7b657c0b4 upstream.
+
+In order to avoid triggering a NULL pointer dereference in
+exynos_pcie_probe() a check must be put in place to detect if
+the init_clk_resources hook is initialized before calling it.
+
+Add the respective function pointer check in exynos_pcie_probe().
+
+Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
+[lorenzo.pieralisi@arm.com: rewrote the commit log]
+Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/dwc/pci-exynos.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/dwc/pci-exynos.c
++++ b/drivers/pci/dwc/pci-exynos.c
+@@ -695,7 +695,8 @@ static int __init exynos_pcie_probe(stru
+                       return ret;
+       }
+-      if (ep->ops && ep->ops->get_clk_resources) {
++      if (ep->ops && ep->ops->get_clk_resources &&
++                      ep->ops->init_clk_resources) {
+               ret = ep->ops->get_clk_resources(ep);
+               if (ret)
+                       return ret;
index 8c904802856ccfc29120dbf58210f1ca19401f20..3cb6125bd47ae627cefc4653729567ef94dcbca8 100644 (file)
@@ -1,3 +1,13 @@
 compiler-gcc.h-add-__attribute__-gnu_inline-to-all-inline-declarations.patch
 x86-asm-add-_asm_arg-constants-for-argument-registers-to-asm-asm.h.patch
 x86-paravirt-make-native_save_fl-extern-inline.patch
+btrfs-fix-duplicate-extents-after-fsync-of-file-with-prealloc-extents.patch
+cpufreq-cppc-set-platform-specific-transition_delay_us.patch
+xprtrdma-fix-corner-cases-when-handling-device-removal.patch
+ocfs2-subsystem.su_mutex-is-required-while-accessing-the-item-ci_parent.patch
+ocfs2-ip_alloc_sem-should-be-taken-in-ocfs2_get_block.patch
+bcm63xx_enet-correct-clock-usage.patch
+bcm63xx_enet-do-not-write-to-random-dma-channel-on-bcm6345.patch
+pci-exynos-fix-a-potential-init_clk_resources-null-pointer-dereference.patch
+crypto-crypto4xx-remove-bad-list_del.patch
+crypto-crypto4xx-fix-crypto4xx_build_pdr-crypto4xx_build_sdr-leak.patch
diff --git a/queue-4.14/xprtrdma-fix-corner-cases-when-handling-device-removal.patch b/queue-4.14/xprtrdma-fix-corner-cases-when-handling-device-removal.patch
new file mode 100644 (file)
index 0000000..88224e2
--- /dev/null
@@ -0,0 +1,83 @@
+From 25524288631fc5b7d33259fca1e0dc38146be5d6 Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Mon, 19 Mar 2018 14:23:16 -0400
+Subject: xprtrdma: Fix corner cases when handling device removal
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 25524288631fc5b7d33259fca1e0dc38146be5d6 upstream.
+
+Michal Kalderon has found some corner cases around device unload
+with active NFS mounts that I didn't have the imagination to test
+when xprtrdma device removal was added last year.
+
+- The ULP device removal handler is responsible for deallocating
+  the PD. That wasn't clear to me initially, and my own testing
+  suggested it was not necessary, but that is incorrect.
+
+- The transport destruction path can no longer assume that there
+  is a valid ID.
+
+- When destroying a transport, ensure that ib_free_cq() is not
+  invoked on a CQ that was already released.
+
+Reported-by: Michal Kalderon <Michal.Kalderon@cavium.com>
+Fixes: bebd031866ca ("xprtrdma: Support unplugging an HCA from ...")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Cc: stable@vger.kernel.org # v4.12+
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sunrpc/xprtrdma/verbs.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -270,7 +270,6 @@ rpcrdma_conn_upcall(struct rdma_cm_id *i
+               wait_for_completion(&ia->ri_remove_done);
+               ia->ri_id = NULL;
+-              ia->ri_pd = NULL;
+               ia->ri_device = NULL;
+               /* Return 1 to ensure the core destroys the id. */
+               return 1;
+@@ -464,7 +463,9 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
+               ia->ri_id->qp = NULL;
+       }
+       ib_free_cq(ep->rep_attr.recv_cq);
++      ep->rep_attr.recv_cq = NULL;
+       ib_free_cq(ep->rep_attr.send_cq);
++      ep->rep_attr.send_cq = NULL;
+       /* The ULP is responsible for ensuring all DMA
+        * mappings and MRs are gone.
+@@ -477,6 +478,8 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
+               rpcrdma_dma_unmap_regbuf(req->rl_recvbuf);
+       }
+       rpcrdma_destroy_mrs(buf);
++      ib_dealloc_pd(ia->ri_pd);
++      ia->ri_pd = NULL;
+       /* Allow waiters to continue */
+       complete(&ia->ri_remove_done);
+@@ -650,14 +653,16 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep
+       cancel_delayed_work_sync(&ep->rep_connect_worker);
+-      if (ia->ri_id->qp) {
++      if (ia->ri_id && ia->ri_id->qp) {
+               rpcrdma_ep_disconnect(ep, ia);
+               rdma_destroy_qp(ia->ri_id);
+               ia->ri_id->qp = NULL;
+       }
+-      ib_free_cq(ep->rep_attr.recv_cq);
+-      ib_free_cq(ep->rep_attr.send_cq);
++      if (ep->rep_attr.recv_cq)
++              ib_free_cq(ep->rep_attr.recv_cq);
++      if (ep->rep_attr.send_cq)
++              ib_free_cq(ep->rep_attr.send_cq);
+ }
+ /* Re-establish a connection after a device removal event.