--- /dev/null
+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;
+ }
--- /dev/null
+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);
+
--- /dev/null
+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;
+ }
+
--- /dev/null
+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) {
--- /dev/null
+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);
--- /dev/null
+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;
--- /dev/null
+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,
--- /dev/null
+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);
--- /dev/null
+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;
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
--- /dev/null
+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.