From: Greg Kroah-Hartman Date: Thu, 20 Oct 2016 14:23:47 +0000 (+0200) Subject: 4.7-stable patches X-Git-Tag: v4.7.10~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6e5944630e235d0af6c6b98f86f232449c91d530;p=thirdparty%2Fkernel%2Fstable-queue.git 4.7-stable patches added patches: asoc-intel-atom-add-a-missing-star-in-a-memcpy-call.patch asoc-nau8825-fix-bug-in-fll-parameter.patch async_pq_val-fix-dma-memory-leak.patch brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch brcmfmac-fix-pmksa-bssid-usage.patch brcmfmac-use-correct-skb-freeing-helper-when-deleting-flowring.patch btrfs-assign-error-values-to-the-correct-bio-structs.patch btrfs-catch-invalid-free-space-trees.patch btrfs-fix-free-space-tree-bitmaps-on-big-endian-systems.patch clk-mvebu-dynamically-allocate-resources-in-armada-cp110-system-controller.patch clk-mvebu-fix-setting-unwanted-flags-in-cp110-gate-clock.patch drivers-base-dma-mapping-page-align-the-size-when-unmap_kernel_range.patch fuse-fix-killing-sid-in-setattr.patch fuse-invalidate-dir-dentry-after-chmod.patch fuse-listxattr-verify-xattr-list.patch i40e-avoid-null-pointer-dereference-and-recursive-errors-on-early-pci-error.patch ib-hfi1-fix-defered-ack-race-with-qp-destroy.patch mei-amthif-fix-deadlock-in-initialization-during-a-reset.patch reiserfs-unlock-superblock-before-calling-reiserfs_quota_on_mount.patch xfs-change-mailing-list-address.patch --- diff --git a/queue-4.7/asoc-intel-atom-add-a-missing-star-in-a-memcpy-call.patch b/queue-4.7/asoc-intel-atom-add-a-missing-star-in-a-memcpy-call.patch new file mode 100644 index 00000000000..27ec25f6f1e --- /dev/null +++ b/queue-4.7/asoc-intel-atom-add-a-missing-star-in-a-memcpy-call.patch @@ -0,0 +1,56 @@ +From 61ab0d403bbd9d5f6e000e3b5734049141b91f6f Mon Sep 17 00:00:00 2001 +From: Nicolas Iooss +Date: Sun, 28 Aug 2016 21:10:04 +0200 +Subject: ASoC: Intel: Atom: add a missing star in a memcpy call + +From: Nicolas Iooss + +commit 61ab0d403bbd9d5f6e000e3b5734049141b91f6f upstream. + +In sst_prepare_and_post_msg(), when a response is received in "block", +the following code gets executed: + + *data = kzalloc(block->size, GFP_KERNEL); + memcpy(data, (void *) block->data, block->size); + +The memcpy() call overwrites the content of the *data pointer instead of +filling the newly-allocated memory (which pointer is hold by *data). +Fix this by merging kzalloc+memcpy into a single kmemdup() call. + +Thanks Joe Perches for suggesting using kmemdup() + +Fixes: 60dc8dbacb00 ("ASoC: Intel: sst: Add some helper functions") +Signed-off-by: Nicolas Iooss +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/intel/atom/sst/sst_pvt.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/sound/soc/intel/atom/sst/sst_pvt.c ++++ b/sound/soc/intel/atom/sst/sst_pvt.c +@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct inte + + if (response) { + ret = sst_wait_timeout(sst, block); +- if (ret < 0) { ++ if (ret < 0) + goto out; +- } else if(block->data) { +- if (!data) +- goto out; +- *data = kzalloc(block->size, GFP_KERNEL); +- if (!(*data)) { ++ ++ if (data && block->data) { ++ *data = kmemdup(block->data, block->size, GFP_KERNEL); ++ if (!*data) { + ret = -ENOMEM; + goto out; +- } else +- memcpy(data, (void *) block->data, block->size); ++ } + } + } + out: diff --git a/queue-4.7/asoc-nau8825-fix-bug-in-fll-parameter.patch b/queue-4.7/asoc-nau8825-fix-bug-in-fll-parameter.patch new file mode 100644 index 00000000000..786240b1ae9 --- /dev/null +++ b/queue-4.7/asoc-nau8825-fix-bug-in-fll-parameter.patch @@ -0,0 +1,31 @@ +From a8961cae29c38e225120c40c3340dbde2f552e60 Mon Sep 17 00:00:00 2001 +From: John Hsu +Date: Tue, 13 Sep 2016 11:56:03 +0800 +Subject: ASoC: nau8825: fix bug in FLL parameter + +From: John Hsu + +commit a8961cae29c38e225120c40c3340dbde2f552e60 upstream. + +In the FLL parameter calculation, the FVCO should choose the maximum one. +The patch is to fix the bug about the wrong FVCO chosen. + +Signed-off-by: John Hsu +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/nau8825.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/soc/codecs/nau8825.c ++++ b/sound/soc/codecs/nau8825.c +@@ -1015,7 +1015,7 @@ static int nau8825_calc_fll_param(unsign + /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional + * input based on FDCO, FREF and FLL ratio. + */ +- fvco = div_u64(fvco << 16, fref * fll_param->ratio); ++ fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); + fll_param->fll_int = (fvco >> 16) & 0x3FF; + fll_param->fll_frac = fvco & 0xFFFF; + return 0; diff --git a/queue-4.7/async_pq_val-fix-dma-memory-leak.patch b/queue-4.7/async_pq_val-fix-dma-memory-leak.patch new file mode 100644 index 00000000000..ee26f2d4148 --- /dev/null +++ b/queue-4.7/async_pq_val-fix-dma-memory-leak.patch @@ -0,0 +1,46 @@ +From c84750906b4818d4929fbf73a4ae6c113b94f52b Mon Sep 17 00:00:00 2001 +From: Justin Maggard +Date: Tue, 4 Oct 2016 13:17:58 -0700 +Subject: async_pq_val: fix DMA memory leak + +From: Justin Maggard + +commit c84750906b4818d4929fbf73a4ae6c113b94f52b upstream. + +Add missing dmaengine_unmap_put(), so we don't OOM during RAID6 sync. + +Fixes: 1786b943dad0 ("async_pq_val: convert to dmaengine_unmap_data") +Signed-off-by: Justin Maggard +Reviewed-by: Dan Williams +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + crypto/async_tx/async_pq.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/crypto/async_tx/async_pq.c ++++ b/crypto/async_tx/async_pq.c +@@ -368,8 +368,6 @@ async_syndrome_val(struct page **blocks, + + dma_set_unmap(tx, unmap); + async_tx_submit(chan, tx, submit); +- +- return tx; + } else { + struct page *p_src = P(blocks, disks); + struct page *q_src = Q(blocks, disks); +@@ -424,9 +422,11 @@ async_syndrome_val(struct page **blocks, + submit->cb_param = cb_param_orig; + submit->flags = flags_orig; + async_tx_sync_epilog(submit); +- +- return NULL; ++ tx = NULL; + } ++ dmaengine_unmap_put(unmap); ++ ++ return tx; + } + EXPORT_SYMBOL_GPL(async_syndrome_val); + diff --git a/queue-4.7/brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch b/queue-4.7/brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch new file mode 100644 index 00000000000..accc453a99e --- /dev/null +++ b/queue-4.7/brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch @@ -0,0 +1,46 @@ +From 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 21 Sep 2016 08:23:24 +0200 +Subject: brcmfmac: fix memory leak in brcmf_fill_bss_param +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rafał Miłecki + +commit 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 upstream. + +This function is called from get_station callback which means that every +time user space was getting/dumping station(s) we were leaking 2 KiB. + +Signed-off-by: Rafał Miłecki +Fixes: 1f0dc59a6de ("brcmfmac: rework .get_station() callback") +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2473,7 +2473,7 @@ static void brcmf_fill_bss_param(struct + WL_BSS_INFO_MAX); + if (err) { + brcmf_err("Failed to get bss info (%d)\n", err); +- return; ++ goto out_kfree; + } + si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); + si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); +@@ -2485,6 +2485,9 @@ static void brcmf_fill_bss_param(struct + si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) + si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; ++ ++out_kfree: ++ kfree(buf); + } + + static s32 diff --git a/queue-4.7/brcmfmac-fix-pmksa-bssid-usage.patch b/queue-4.7/brcmfmac-fix-pmksa-bssid-usage.patch new file mode 100644 index 00000000000..7d67d98a980 --- /dev/null +++ b/queue-4.7/brcmfmac-fix-pmksa-bssid-usage.patch @@ -0,0 +1,56 @@ +From 7703773ef1d85b40433902a8da20167331597e4a Mon Sep 17 00:00:00 2001 +From: Nicolas Iooss +Date: Tue, 23 Aug 2016 11:37:17 +0200 +Subject: brcmfmac: fix pmksa->bssid usage + +From: Nicolas Iooss + +commit 7703773ef1d85b40433902a8da20167331597e4a upstream. + +The struct cfg80211_pmksa defines its bssid field as: + + const u8 *bssid; + +contrary to struct brcmf_pmksa, which uses: + + u8 bssid[ETH_ALEN]; + +Therefore in brcmf_cfg80211_del_pmksa(), &pmksa->bssid takes the address +of this field (of type u8**), not the one of its content (which would be +u8*). Remove the & operator to make brcmf_dbg("%pM") and memcmp() +behave as expected. + +This bug have been found using a custom static checker (which checks the +usage of %p... attributes at build time). It has been introduced in +commit 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code"), +which replaced pmksa->bssid by &pmksa->bssid while refactoring the code, +without modifying struct cfg80211_pmksa definition. + +Replace &pmk[i].bssid with pmk[i].bssid too to make the code clearer, +this change does not affect the semantic. + +Fixes: 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code") +Signed-off-by: Nicolas Iooss +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3824,11 +3824,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w + if (!check_vif_up(ifp->vif)) + return -EIO; + +- brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid); ++ brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid); + + npmk = le32_to_cpu(cfg->pmk_list.npmk); + for (i = 0; i < npmk; i++) +- if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN)) ++ if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN)) + break; + + if ((npmk > 0) && (i < npmk)) { diff --git a/queue-4.7/brcmfmac-use-correct-skb-freeing-helper-when-deleting-flowring.patch b/queue-4.7/brcmfmac-use-correct-skb-freeing-helper-when-deleting-flowring.patch new file mode 100644 index 00000000000..f44711bec36 --- /dev/null +++ b/queue-4.7/brcmfmac-use-correct-skb-freeing-helper-when-deleting-flowring.patch @@ -0,0 +1,62 @@ +From 7f00ee2bbc630900ba16fc2690473f3e2db0e264 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 27 Sep 2016 14:11:04 +0200 +Subject: brcmfmac: use correct skb freeing helper when deleting flowring +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rafał Miłecki + +commit 7f00ee2bbc630900ba16fc2690473f3e2db0e264 upstream. + +Flowrings contain skbs waiting for transmission that were passed to us +by netif. It means we checked every one of them looking for 802.1x +Ethernet type. When deleting flowring we have to use freeing function +that will check for 802.1x type as well. + +Freeing skbs without a proper check was leading to counter not being +properly decreased. This was triggering a WARNING every time +brcmf_netdev_wait_pend8021x was called. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c +@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct + + void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid) + { ++ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); + struct brcmf_flowring_ring *ring; ++ struct brcmf_if *ifp; + u16 hash_idx; ++ u8 ifidx; + struct sk_buff *skb; + + ring = flow->rings[flowid]; + if (!ring) + return; ++ ++ ifidx = brcmf_flowring_ifidx_get(flow, flowid); ++ ifp = brcmf_get_ifp(bus_if->drvr, ifidx); ++ + brcmf_flowring_block(flow, flowid, false); + hash_idx = ring->hash_id; + flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX; +@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_ + + skb = skb_dequeue(&ring->skblist); + while (skb) { +- brcmu_pkt_buf_free_skb(skb); ++ brcmf_txfinalize(ifp, skb, false); + skb = skb_dequeue(&ring->skblist); + } + diff --git a/queue-4.7/btrfs-assign-error-values-to-the-correct-bio-structs.patch b/queue-4.7/btrfs-assign-error-values-to-the-correct-bio-structs.patch new file mode 100644 index 00000000000..51d8876944e --- /dev/null +++ b/queue-4.7/btrfs-assign-error-values-to-the-correct-bio-structs.patch @@ -0,0 +1,39 @@ +From 14155cafeadda946376260e2ad5d39a0528a332f Mon Sep 17 00:00:00 2001 +From: Junjie Mao +Date: Mon, 17 Oct 2016 09:20:25 +0800 +Subject: btrfs: assign error values to the correct bio structs + +From: Junjie Mao + +commit 14155cafeadda946376260e2ad5d39a0528a332f upstream. + +Fixes: 4246a0b63bd8 ("block: add a bi_error field to struct bio") +Signed-off-by: Junjie Mao +Acked-by: David Sterba +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/compression.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -690,7 +690,7 @@ int btrfs_submit_compressed_read(struct + ret = btrfs_map_bio(root, READ, comp_bio, + mirror_num, 0); + if (ret) { +- bio->bi_error = ret; ++ comp_bio->bi_error = ret; + bio_endio(comp_bio); + } + +@@ -719,7 +719,7 @@ int btrfs_submit_compressed_read(struct + + ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); + if (ret) { +- bio->bi_error = ret; ++ comp_bio->bi_error = ret; + bio_endio(comp_bio); + } + diff --git a/queue-4.7/btrfs-catch-invalid-free-space-trees.patch b/queue-4.7/btrfs-catch-invalid-free-space-trees.patch new file mode 100644 index 00000000000..0d774c03a8d --- /dev/null +++ b/queue-4.7/btrfs-catch-invalid-free-space-trees.patch @@ -0,0 +1,118 @@ +From 6675df311db87aa2107a04ef97e19420953cbace Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Thu, 22 Sep 2016 17:24:22 -0700 +Subject: Btrfs: catch invalid free space trees +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Omar Sandoval + +commit 6675df311db87aa2107a04ef97e19420953cbace upstream. + +There are two separate issues that can lead to corrupted free space +trees. + +1. The free space tree bitmaps had an endianness issue on big-endian + systems which is fixed by an earlier patch in this series. +2. btrfs-progs before v4.7.3 modified filesystems without updating the + free space tree. + +To catch both of these issues at once, we need to force the free space +tree to be rebuilt. To do so, add a FREE_SPACE_TREE_VALID compat_ro bit. +If the bit isn't set, we know that it was either produced by a broken +big-endian kernel or may have been corrupted by btrfs-progs. + +This also provides us with a way to add rudimentary read-write support +for the free space tree to btrfs-progs: it can just clear this bit and +have the kernel rebuild the free space tree. + +Tested-by: Holger Hoffstätte +Tested-by: Chandan Rajendra +Signed-off-by: Omar Sandoval +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.h | 3 ++- + fs/btrfs/disk-io.c | 9 +++++++++ + fs/btrfs/free-space-tree.c | 2 ++ + include/uapi/linux/btrfs.h | 12 +++++++++++- + 4 files changed, 24 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -265,7 +265,8 @@ struct btrfs_super_block { + #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL + + #define BTRFS_FEATURE_COMPAT_RO_SUPP \ +- (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) ++ (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \ ++ BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID) + + #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL + #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -2528,6 +2528,7 @@ int open_ctree(struct super_block *sb, + int num_backups_tried = 0; + int backup_index = 0; + int max_active; ++ int clear_free_space_tree = 0; + + tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); + chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); +@@ -3129,6 +3130,14 @@ retry_root_backup: + + if (btrfs_test_opt(tree_root, CLEAR_CACHE) && + btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { ++ clear_free_space_tree = 1; ++ } else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) && ++ !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) { ++ btrfs_warn(fs_info, "free space tree is invalid"); ++ clear_free_space_tree = 1; ++ } ++ ++ if (clear_free_space_tree) { + btrfs_info(fs_info, "clearing free space tree"); + ret = btrfs_clear_free_space_tree(fs_info); + if (ret) { +--- a/fs/btrfs/free-space-tree.c ++++ b/fs/btrfs/free-space-tree.c +@@ -1182,6 +1182,7 @@ int btrfs_create_free_space_tree(struct + } + + btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); ++ btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); + fs_info->creating_free_space_tree = 0; + + ret = btrfs_commit_transaction(trans, tree_root); +@@ -1250,6 +1251,7 @@ int btrfs_clear_free_space_tree(struct b + return PTR_ERR(trans); + + btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE); ++ btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID); + fs_info->free_space_root = NULL; + + ret = clear_free_space_tree(trans, free_space_root); +--- a/include/uapi/linux/btrfs.h ++++ b/include/uapi/linux/btrfs.h +@@ -239,7 +239,17 @@ struct btrfs_ioctl_fs_info_args { + * Used by: + * struct btrfs_ioctl_feature_flags + */ +-#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) ++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) ++/* ++ * Older kernels (< 4.9) on big-endian systems produced broken free space tree ++ * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions ++ * < 4.7.3). If this bit is clear, then the free space tree cannot be trusted. ++ * btrfs-progs can also intentionally clear this bit to ask the kernel to ++ * rebuild the free space tree, however this might not work on older kernels ++ * that do not know about this bit. If not sure, clear the cache manually on ++ * first mount when booting older kernel versions. ++ */ ++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1) + + #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) + #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) diff --git a/queue-4.7/btrfs-fix-free-space-tree-bitmaps-on-big-endian-systems.patch b/queue-4.7/btrfs-fix-free-space-tree-bitmaps-on-big-endian-systems.patch new file mode 100644 index 00000000000..094abd0c887 --- /dev/null +++ b/queue-4.7/btrfs-fix-free-space-tree-bitmaps-on-big-endian-systems.patch @@ -0,0 +1,257 @@ +From 2fe1d55134fce05c17ea118a2e37a4af771887bc Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Thu, 22 Sep 2016 17:24:20 -0700 +Subject: Btrfs: fix free space tree bitmaps on big-endian systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Omar Sandoval + +commit 2fe1d55134fce05c17ea118a2e37a4af771887bc upstream. + +In convert_free_space_to_{bitmaps,extents}(), we buffer the free space +bitmaps in memory and copy them directly to/from the extent buffers with +{read,write}_extent_buffer(). The extent buffer bitmap helpers use byte +granularity, which is equivalent to a little-endian bitmap. This means +that on big-endian systems, the in-memory bitmaps will be written to +disk byte-swapped. To fix this, use byte-granularity for the bitmaps in +memory. + +Fixes: a5ed91828518 ("Btrfs: implement the free space B-tree") +Tested-by: Holger Hoffstätte +Tested-by: Chandan Rajendra +Signed-off-by: Omar Sandoval +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/extent_io.c | 64 ++++++++++++++++++++++++++++++++------------- + fs/btrfs/extent_io.h | 22 +++++++++++++++ + fs/btrfs/free-space-tree.c | 17 +++++------ + 3 files changed, 76 insertions(+), 27 deletions(-) + +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -5508,17 +5508,45 @@ void copy_extent_buffer(struct extent_bu + } + } + +-/* +- * The extent buffer bitmap operations are done with byte granularity because +- * bitmap items are not guaranteed to be aligned to a word and therefore a +- * single word in a bitmap may straddle two pages in the extent buffer. +- */ +-#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) +-#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) +-#define BITMAP_FIRST_BYTE_MASK(start) \ +- ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) +-#define BITMAP_LAST_BYTE_MASK(nbits) \ +- (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) ++void le_bitmap_set(u8 *map, unsigned int start, int len) ++{ ++ u8 *p = map + BIT_BYTE(start); ++ const unsigned int size = start + len; ++ int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE); ++ u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start); ++ ++ while (len - bits_to_set >= 0) { ++ *p |= mask_to_set; ++ len -= bits_to_set; ++ bits_to_set = BITS_PER_BYTE; ++ mask_to_set = ~(u8)0; ++ p++; ++ } ++ if (len) { ++ mask_to_set &= BITMAP_LAST_BYTE_MASK(size); ++ *p |= mask_to_set; ++ } ++} ++ ++void le_bitmap_clear(u8 *map, unsigned int start, int len) ++{ ++ u8 *p = map + BIT_BYTE(start); ++ const unsigned int size = start + len; ++ int bits_to_clear = BITS_PER_BYTE - (start % BITS_PER_BYTE); ++ u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(start); ++ ++ while (len - bits_to_clear >= 0) { ++ *p &= ~mask_to_clear; ++ len -= bits_to_clear; ++ bits_to_clear = BITS_PER_BYTE; ++ mask_to_clear = ~(u8)0; ++ p++; ++ } ++ if (len) { ++ mask_to_clear &= BITMAP_LAST_BYTE_MASK(size); ++ *p &= ~mask_to_clear; ++ } ++} + + /* + * eb_bitmap_offset() - calculate the page and offset of the byte containing the +@@ -5562,7 +5590,7 @@ static inline void eb_bitmap_offset(stru + int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, + unsigned long nr) + { +- char *kaddr; ++ u8 *kaddr; + struct page *page; + unsigned long i; + size_t offset; +@@ -5584,13 +5612,13 @@ int extent_buffer_test_bit(struct extent + void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, + unsigned long pos, unsigned long len) + { +- char *kaddr; ++ u8 *kaddr; + struct page *page; + unsigned long i; + size_t offset; + const unsigned int size = pos + len; + int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE); +- unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos); ++ u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(pos); + + eb_bitmap_offset(eb, start, pos, &i, &offset); + page = eb->pages[i]; +@@ -5601,7 +5629,7 @@ void extent_buffer_bitmap_set(struct ext + kaddr[offset] |= mask_to_set; + len -= bits_to_set; + bits_to_set = BITS_PER_BYTE; +- mask_to_set = ~0U; ++ mask_to_set = ~(u8)0; + if (++offset >= PAGE_SIZE && len > 0) { + offset = 0; + page = eb->pages[++i]; +@@ -5626,13 +5654,13 @@ void extent_buffer_bitmap_set(struct ext + void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, + unsigned long pos, unsigned long len) + { +- char *kaddr; ++ u8 *kaddr; + struct page *page; + unsigned long i; + size_t offset; + const unsigned int size = pos + len; + int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE); +- unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos); ++ u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos); + + eb_bitmap_offset(eb, start, pos, &i, &offset); + page = eb->pages[i]; +@@ -5643,7 +5671,7 @@ void extent_buffer_bitmap_clear(struct e + kaddr[offset] &= ~mask_to_clear; + len -= bits_to_clear; + bits_to_clear = BITS_PER_BYTE; +- mask_to_clear = ~0U; ++ mask_to_clear = ~(u8)0; + if (++offset >= PAGE_SIZE && len > 0) { + offset = 0; + page = eb->pages[++i]; +--- a/fs/btrfs/extent_io.h ++++ b/fs/btrfs/extent_io.h +@@ -58,6 +58,28 @@ + */ + #define EXTENT_PAGE_PRIVATE 1 + ++/* ++ * The extent buffer bitmap operations are done with byte granularity instead of ++ * word granularity for two reasons: ++ * 1. The bitmaps must be little-endian on disk. ++ * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a ++ * single word in a bitmap may straddle two pages in the extent buffer. ++ */ ++#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) ++#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) ++#define BITMAP_FIRST_BYTE_MASK(start) \ ++ ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) ++#define BITMAP_LAST_BYTE_MASK(nbits) \ ++ (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) ++ ++static inline int le_test_bit(int nr, const u8 *addr) ++{ ++ return 1U & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE-1))); ++} ++ ++extern void le_bitmap_set(u8 *map, unsigned int start, int len); ++extern void le_bitmap_clear(u8 *map, unsigned int start, int len); ++ + struct extent_state; + struct btrfs_root; + struct btrfs_io_bio; +--- a/fs/btrfs/free-space-tree.c ++++ b/fs/btrfs/free-space-tree.c +@@ -151,7 +151,7 @@ static inline u32 free_space_bitmap_size + return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE); + } + +-static unsigned long *alloc_bitmap(u32 bitmap_size) ++static u8 *alloc_bitmap(u32 bitmap_size) + { + void *mem; + +@@ -180,8 +180,7 @@ int convert_free_space_to_bitmaps(struct + struct btrfs_free_space_info *info; + struct btrfs_key key, found_key; + struct extent_buffer *leaf; +- unsigned long *bitmap; +- char *bitmap_cursor; ++ u8 *bitmap, *bitmap_cursor; + u64 start, end; + u64 bitmap_range, i; + u32 bitmap_size, flags, expected_extent_count; +@@ -231,7 +230,7 @@ int convert_free_space_to_bitmaps(struct + block_group->sectorsize); + last = div_u64(found_key.objectid + found_key.offset - start, + block_group->sectorsize); +- bitmap_set(bitmap, first, last - first); ++ le_bitmap_set(bitmap, first, last - first); + + extent_count++; + nr++; +@@ -269,7 +268,7 @@ int convert_free_space_to_bitmaps(struct + goto out; + } + +- bitmap_cursor = (char *)bitmap; ++ bitmap_cursor = bitmap; + bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS; + i = start; + while (i < end) { +@@ -318,7 +317,7 @@ int convert_free_space_to_extents(struct + struct btrfs_free_space_info *info; + struct btrfs_key key, found_key; + struct extent_buffer *leaf; +- unsigned long *bitmap; ++ u8 *bitmap; + u64 start, end; + /* Initialize to silence GCC. */ + u64 extent_start = 0; +@@ -362,7 +361,7 @@ int convert_free_space_to_extents(struct + break; + } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { + unsigned long ptr; +- char *bitmap_cursor; ++ u8 *bitmap_cursor; + u32 bitmap_pos, data_size; + + ASSERT(found_key.objectid >= start); +@@ -372,7 +371,7 @@ int convert_free_space_to_extents(struct + bitmap_pos = div_u64(found_key.objectid - start, + block_group->sectorsize * + BITS_PER_BYTE); +- bitmap_cursor = ((char *)bitmap) + bitmap_pos; ++ bitmap_cursor = bitmap + bitmap_pos; + data_size = free_space_bitmap_size(found_key.offset, + block_group->sectorsize); + +@@ -409,7 +408,7 @@ int convert_free_space_to_extents(struct + offset = start; + bitnr = 0; + while (offset < end) { +- bit = !!test_bit(bitnr, bitmap); ++ bit = !!le_test_bit(bitnr, bitmap); + if (prev_bit == 0 && bit == 1) { + extent_start = offset; + } else if (prev_bit == 1 && bit == 0) { diff --git a/queue-4.7/clk-mvebu-dynamically-allocate-resources-in-armada-cp110-system-controller.patch b/queue-4.7/clk-mvebu-dynamically-allocate-resources-in-armada-cp110-system-controller.patch new file mode 100644 index 00000000000..5061dfd97db --- /dev/null +++ b/queue-4.7/clk-mvebu-dynamically-allocate-resources-in-armada-cp110-system-controller.patch @@ -0,0 +1,96 @@ +From a0245eb76ad0f652f1eb14f48ca2d3c4391aef66 Mon Sep 17 00:00:00 2001 +From: Marcin Wojtas +Date: Wed, 21 Sep 2016 11:05:58 +0200 +Subject: clk: mvebu: dynamically allocate resources in Armada CP110 system controller + +From: Marcin Wojtas + +commit a0245eb76ad0f652f1eb14f48ca2d3c4391aef66 upstream. + +Original commit, which added support for Armada CP110 system controller +used global variables for storing all clock information. It worked +fine for Armada 7k SoC, with single CP110 block. After dual-CP110 Armada 8k +was introduced, the data got overwritten and corrupted. + +This patch fixes the issue by allocating resources dynamically in the +driver probe and storing it as platform drvdata. + +Fixes: d3da3eaef7f4 ("clk: mvebu: new driver for Armada CP110 system ...") +Signed-off-by: Marcin Wojtas +Reviewed-by: Thomas Petazzoni +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/mvebu/cp110-system-controller.c | 29 +++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +--- a/drivers/clk/mvebu/cp110-system-controller.c ++++ b/drivers/clk/mvebu/cp110-system-controller.c +@@ -81,13 +81,6 @@ enum { + #define CP110_GATE_EIP150 25 + #define CP110_GATE_EIP197 26 + +-static struct clk *cp110_clks[CP110_CLK_NUM]; +- +-static struct clk_onecell_data cp110_clk_data = { +- .clks = cp110_clks, +- .clk_num = CP110_CLK_NUM, +-}; +- + struct cp110_gate_clk { + struct clk_hw hw; + struct regmap *regmap; +@@ -196,7 +189,8 @@ static int cp110_syscon_clk_probe(struct + struct regmap *regmap; + struct device_node *np = pdev->dev.of_node; + const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name; +- struct clk *clk; ++ struct clk_onecell_data *cp110_clk_data; ++ struct clk *clk, **cp110_clks; + u32 nand_clk_ctrl; + int i, ret; + +@@ -209,6 +203,20 @@ static int cp110_syscon_clk_probe(struct + if (ret) + return ret; + ++ cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *), ++ CP110_CLK_NUM, GFP_KERNEL); ++ if (!cp110_clks) ++ return -ENOMEM; ++ ++ cp110_clk_data = devm_kzalloc(&pdev->dev, ++ sizeof(*cp110_clk_data), ++ GFP_KERNEL); ++ if (!cp110_clk_data) ++ return -ENOMEM; ++ ++ cp110_clk_data->clks = cp110_clks; ++ cp110_clk_data->clk_num = CP110_CLK_NUM; ++ + /* Register the APLL which is the root of the clk tree */ + of_property_read_string_index(np, "core-clock-output-names", + CP110_CORE_APLL, &apll_name); +@@ -336,10 +344,12 @@ static int cp110_syscon_clk_probe(struct + cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk; + } + +- ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data); ++ ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data); + if (ret) + goto fail_clk_add; + ++ platform_set_drvdata(pdev, cp110_clks); ++ + return 0; + + fail_clk_add: +@@ -366,6 +376,7 @@ fail0: + + static int cp110_syscon_clk_remove(struct platform_device *pdev) + { ++ struct clk **cp110_clks = platform_get_drvdata(pdev); + int i; + + of_clk_del_provider(pdev->dev.of_node); diff --git a/queue-4.7/clk-mvebu-fix-setting-unwanted-flags-in-cp110-gate-clock.patch b/queue-4.7/clk-mvebu-fix-setting-unwanted-flags-in-cp110-gate-clock.patch new file mode 100644 index 00000000000..dc08d23138b --- /dev/null +++ b/queue-4.7/clk-mvebu-fix-setting-unwanted-flags-in-cp110-gate-clock.patch @@ -0,0 +1,37 @@ +From ad715b268a501533ecb2e891a624841d1bb5137c Mon Sep 17 00:00:00 2001 +From: Marcin Wojtas +Date: Wed, 21 Sep 2016 11:05:57 +0200 +Subject: clk: mvebu: fix setting unwanted flags in CP110 gate clock + +From: Marcin Wojtas + +commit ad715b268a501533ecb2e891a624841d1bb5137c upstream. + +Armada CP110 system controller comprises its own routine responsble +for registering gate clocks. Among others 'flags' field in +struct clk_init_data was not set, using a random values, which +may cause an unpredicted behavior. + +This patch fixes the problem by resetting all fields of clk_init_data +before assigning values for all gated clocks of Armada 7k/8k SoCs family. + +Fixes: d3da3eaef7f4 ("clk: mvebu: new driver for Armada CP110 system ...") +Signed-off-by: Marcin Wojtas +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/mvebu/cp110-system-controller.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/clk/mvebu/cp110-system-controller.c ++++ b/drivers/clk/mvebu/cp110-system-controller.c +@@ -142,6 +142,8 @@ static struct clk *cp110_register_gate(c + if (!gate) + return ERR_PTR(-ENOMEM); + ++ memset(&init, 0, sizeof(init)); ++ + init.name = name; + init.ops = &cp110_gate_ops; + init.parent_names = &parent_name; diff --git a/queue-4.7/drivers-base-dma-mapping-page-align-the-size-when-unmap_kernel_range.patch b/queue-4.7/drivers-base-dma-mapping-page-align-the-size-when-unmap_kernel_range.patch new file mode 100644 index 00000000000..dc295012c17 --- /dev/null +++ b/queue-4.7/drivers-base-dma-mapping-page-align-the-size-when-unmap_kernel_range.patch @@ -0,0 +1,65 @@ +From 85714108e673cdebf1b96abfd50fb02a29e37577 Mon Sep 17 00:00:00 2001 +From: Peng Fan +Date: Thu, 21 Jul 2016 16:04:21 +0800 +Subject: drivers: base: dma-mapping: page align the size when unmap_kernel_range + +From: Peng Fan + +commit 85714108e673cdebf1b96abfd50fb02a29e37577 upstream. + +When dma_common_free_remap, the input parameter 'size' may not +be page aligned. And, met kernel warning when doing iommu dma +for usb on i.MX8 platform: +" +WARNING: CPU: 0 PID: 869 at mm/vmalloc.c:70 vunmap_page_range+0x1cc/0x1d0() +Modules linked in: +CPU: 0 PID: 869 Comm: kworker/u8:2 Not tainted 4.1.12-00444-gc5f9d1d-dirty #147 +Hardware name: Freescale i.MX8DV Sabreauto (DT) +Workqueue: ci_otg ci_otg_work +Call trace: +[] dump_backtrace+0x0/0x124 +[] show_stack+0x10/0x1c +[] dump_stack+0x84/0xc8 +[] warn_slowpath_common+0x98/0xd0 +[] warn_slowpath_null+0x14/0x20 +[] vunmap_page_range+0x1c8/0x1d0 +[] unmap_kernel_range+0x20/0x88 +[] dma_common_free_remap+0x74/0x84 +[] __iommu_free_attrs+0x9c/0x178 +[] ehci_mem_cleanup+0x140/0x194 +[] ehci_stop+0x8c/0xdc +[] usb_remove_hcd+0xf0/0x1cc +[] host_stop+0x1c/0x58 +[] ci_otg_work+0xdc/0x120 +[] process_one_work+0x134/0x33c +[] worker_thread+0x13c/0x47c +[] kthread+0xd8/0xf0 +" + +For dma_common_pages_remap: +dma_common_pages_remap + |->get_vm_area_caller + |->__get_vm_area_node + |->size = PAGE_ALIGN(size); Round up to page aligned + +So, in dma_common_free_remap, we also need a page aligned size, +pass 'PAGE_ALIGN(size)' to unmap_kernel_range. + +Signed-off-by: Peng Fan +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/dma-mapping.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/dma-mapping.c ++++ b/drivers/base/dma-mapping.c +@@ -334,7 +334,7 @@ void dma_common_free_remap(void *cpu_add + return; + } + +- unmap_kernel_range((unsigned long)cpu_addr, size); ++ unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size)); + vunmap(cpu_addr); + } + #endif diff --git a/queue-4.7/fuse-fix-killing-sid-in-setattr.patch b/queue-4.7/fuse-fix-killing-sid-in-setattr.patch new file mode 100644 index 00000000000..0cd1f1b0231 --- /dev/null +++ b/queue-4.7/fuse-fix-killing-sid-in-setattr.patch @@ -0,0 +1,75 @@ +From a09f99eddef44035ec764075a37bace8181bec38 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 1 Oct 2016 07:32:32 +0200 +Subject: fuse: fix killing s[ug]id in setattr + +From: Miklos Szeredi + +commit a09f99eddef44035ec764075a37bace8181bec38 upstream. + +Fuse allowed VFS to set mode in setattr in order to clear suid/sgid on +chown and truncate, and (since writeback_cache) write. The problem with +this is that it'll potentially restore a stale mode. + +The poper fix would be to let the filesystems do the suid/sgid clearing on +the relevant operations. Possibly some are already doing it but there's no +way we can detect this. + +So fix this by refreshing and recalculating the mode. Do this only if +ATTR_KILL_S[UG]ID is set to not destroy performance for writes. This is +still racy but the size of the window is reduced. + +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1701,16 +1701,40 @@ error: + static int fuse_setattr(struct dentry *entry, struct iattr *attr) + { + struct inode *inode = d_inode(entry); ++ struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; + int ret; + + if (!fuse_allow_current_process(get_fuse_conn(inode))) + return -EACCES; + +- if (attr->ia_valid & ATTR_FILE) +- ret = fuse_do_setattr(inode, attr, attr->ia_file); +- else +- ret = fuse_do_setattr(inode, attr, NULL); ++ if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { ++ int kill; + ++ attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ++ ATTR_MODE); ++ /* ++ * ia_mode calculation may have used stale i_mode. Refresh and ++ * recalculate. ++ */ ++ ret = fuse_do_getattr(inode, NULL, file); ++ if (ret) ++ return ret; ++ ++ attr->ia_mode = inode->i_mode; ++ kill = should_remove_suid(entry); ++ if (kill & ATTR_KILL_SUID) { ++ attr->ia_valid |= ATTR_MODE; ++ attr->ia_mode &= ~S_ISUID; ++ } ++ if (kill & ATTR_KILL_SGID) { ++ attr->ia_valid |= ATTR_MODE; ++ attr->ia_mode &= ~S_ISGID; ++ } ++ } ++ if (!attr->ia_valid) ++ return 0; ++ ++ ret = fuse_do_setattr(inode, attr, file); + if (!ret) { + /* Directory mode changed, may need to revalidate access */ + if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) diff --git a/queue-4.7/fuse-invalidate-dir-dentry-after-chmod.patch b/queue-4.7/fuse-invalidate-dir-dentry-after-chmod.patch new file mode 100644 index 00000000000..98fb8f7f745 --- /dev/null +++ b/queue-4.7/fuse-invalidate-dir-dentry-after-chmod.patch @@ -0,0 +1,58 @@ +From 5e2b8828ff3d79aca8c3a1730652758753205b61 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 1 Oct 2016 07:32:32 +0200 +Subject: fuse: invalidate dir dentry after chmod +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Miklos Szeredi + +commit 5e2b8828ff3d79aca8c3a1730652758753205b61 upstream. + +Without "default_permissions" the userspace filesystem's lookup operation +needs to perform the check for search permission on the directory. + +If directory does not allow search for everyone (this is quite rare) then +userspace filesystem has to set entry timeout to zero to make sure +permissions are always performed. + +Changing the mode bits of the directory should also invalidate the +(previously cached) dentry to make sure the next lookup will have a chance +of updating the timeout, if needed. + +Reported-by: Jean-Pierre André +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1701,14 +1701,22 @@ error: + static int fuse_setattr(struct dentry *entry, struct iattr *attr) + { + struct inode *inode = d_inode(entry); ++ int ret; + + if (!fuse_allow_current_process(get_fuse_conn(inode))) + return -EACCES; + + if (attr->ia_valid & ATTR_FILE) +- return fuse_do_setattr(inode, attr, attr->ia_file); ++ ret = fuse_do_setattr(inode, attr, attr->ia_file); + else +- return fuse_do_setattr(inode, attr, NULL); ++ ret = fuse_do_setattr(inode, attr, NULL); ++ ++ if (!ret) { ++ /* Directory mode changed, may need to revalidate access */ ++ if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE)) ++ fuse_invalidate_entry_cache(entry); ++ } ++ return ret; + } + + static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, diff --git a/queue-4.7/fuse-listxattr-verify-xattr-list.patch b/queue-4.7/fuse-listxattr-verify-xattr-list.patch new file mode 100644 index 00000000000..064751f218a --- /dev/null +++ b/queue-4.7/fuse-listxattr-verify-xattr-list.patch @@ -0,0 +1,56 @@ +From cb3ae6d25a5471be62bfe6ac1fccc0e91edeaba0 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Sat, 1 Oct 2016 07:32:32 +0200 +Subject: fuse: listxattr: verify xattr list + +From: Miklos Szeredi + +commit cb3ae6d25a5471be62bfe6ac1fccc0e91edeaba0 upstream. + +Make sure userspace filesystem is returning a well formed list of xattr +names (zero or more nonzero length, null terminated strings). + +[Michael Theall: only verify in the nonzero size case] + +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1800,6 +1800,23 @@ static ssize_t fuse_getxattr(struct dent + return ret; + } + ++static int fuse_verify_xattr_list(char *list, size_t size) ++{ ++ size_t origsize = size; ++ ++ while (size) { ++ size_t thislen = strnlen(list, size); ++ ++ if (!thislen || thislen == size) ++ return -EIO; ++ ++ size -= thislen + 1; ++ list += thislen + 1; ++ } ++ ++ return origsize; ++} ++ + static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) + { + struct inode *inode = d_inode(entry); +@@ -1835,6 +1852,8 @@ static ssize_t fuse_listxattr(struct den + ret = fuse_simple_request(fc, &args); + if (!ret && !size) + ret = outarg.size; ++ if (ret > 0 && size) ++ ret = fuse_verify_xattr_list(list, ret); + if (ret == -ENOSYS) { + fc->no_listxattr = 1; + ret = -EOPNOTSUPP; diff --git a/queue-4.7/i40e-avoid-null-pointer-dereference-and-recursive-errors-on-early-pci-error.patch b/queue-4.7/i40e-avoid-null-pointer-dereference-and-recursive-errors-on-early-pci-error.patch new file mode 100644 index 00000000000..aa7a9f7fd7b --- /dev/null +++ b/queue-4.7/i40e-avoid-null-pointer-dereference-and-recursive-errors-on-early-pci-error.patch @@ -0,0 +1,67 @@ +From edfc23ee3e0ebbb6713d7574ab1b00abff178f6c Mon Sep 17 00:00:00 2001 +From: Guilherme G Piccoli +Date: Mon, 3 Oct 2016 00:31:12 -0700 +Subject: i40e: avoid NULL pointer dereference and recursive errors on early PCI error + +From: Guilherme G Piccoli + +commit edfc23ee3e0ebbb6713d7574ab1b00abff178f6c upstream. + +Although rare, it's possible to hit PCI error early on device +probe, meaning possibly some structs are not entirely initialized, +and some might even be completely uninitialized, leading to NULL +pointer dereference. + +The i40e driver currently presents a "bad" behavior if device hits +such early PCI error: firstly, the struct i40e_pf might not be +attached to pci_dev yet, leading to a NULL pointer dereference on +access to pf->state. + +Even checking if the struct is NULL and avoiding the access in that +case isn't enough, since the driver cannot recover from PCI error +that early; in our experiments we saw multiple failures on kernel +log, like: + + [549.664] i40e 0007:01:00.1: Initial pf_reset failed: -15 + [549.664] i40e: probe of 0007:01:00.1 failed with error -15 + [...] + [871.644] i40e 0007:01:00.1: The driver for the device stopped because the + device firmware failed to init. Try updating your NVM image. + [871.644] i40e: probe of 0007:01:00.1 failed with error -32 + [...] + [872.516] i40e 0007:01:00.0: ARQ: Unknown event 0x0000 ignored + +Between the first probe failure (error -15) and the second (error -32) +another PCI error happened due to the first bad probe. Also, driver +started to flood console with those ARQ event messages. + +This patch will prevent these issues by allowing error recovery +mechanism to remove the failed device from the system instead of +trying to recover from early PCI errors during device probe. + +Signed-off-by: Guilherme G Piccoli +Acked-by: Jacob Keller +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/i40e/i40e_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/ethernet/intel/i40e/i40e_main.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c +@@ -11415,6 +11415,12 @@ static pci_ers_result_t i40e_pci_error_d + + dev_info(&pdev->dev, "%s: error %d\n", __func__, error); + ++ if (!pf) { ++ dev_info(&pdev->dev, ++ "Cannot recover - error happened during device probe\n"); ++ return PCI_ERS_RESULT_DISCONNECT; ++ } ++ + /* shutdown all operations */ + if (!test_bit(__I40E_SUSPENDED, &pf->state)) { + rtnl_lock(); diff --git a/queue-4.7/ib-hfi1-fix-defered-ack-race-with-qp-destroy.patch b/queue-4.7/ib-hfi1-fix-defered-ack-race-with-qp-destroy.patch new file mode 100644 index 00000000000..bce9d63e18e --- /dev/null +++ b/queue-4.7/ib-hfi1-fix-defered-ack-race-with-qp-destroy.patch @@ -0,0 +1,61 @@ +From 72f53af2651957b0b9d6dead72a393eaf9a2c3be Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Sun, 25 Sep 2016 07:41:46 -0700 +Subject: IB/hfi1: Fix defered ack race with qp destroy + +From: Mike Marciniszyn + +commit 72f53af2651957b0b9d6dead72a393eaf9a2c3be upstream. + +There is a a bug in defered ack stuff that causes a race with the +destroy of a QP. + +A packet causes a defered ack to be pended by putting the QP +into an rcd queue. + +A return from the driver interrupt processing will process that rcd +queue of QPs and attempt to do a direct send of the ack. At this +point no locks are held and the above QP could now be put in the reset +state in the qp destroy logic. A refcount protects the QP while it +is in the rcd queue so it isn't going anywhere yet. + +If the direct send fails to allocate a pio buffer, +hfi1_schedule_send() is called to trigger sending an ack from the +send engine. There is no state test in that code path. + +The refcount is then dropped from the driver.c caller +potentially allowing the qp destroy to continue from its +refcount wait in parallel with the workqueue scheduling of the qp. + +Reviewed-by: Dennis Dalessandro +Signed-off-by: Mike Marciniszyn +Signed-off-by: Dennis Dalessandro +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/hfi1/rc.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/hfi1/rc.c ++++ b/drivers/infiniband/hw/hfi1/rc.c +@@ -889,8 +889,10 @@ void hfi1_send_rc_ack(struct hfi1_ctxtda + return; + + queue_ack: +- this_cpu_inc(*ibp->rvp.rc_qacks); + spin_lock_irqsave(&qp->s_lock, flags); ++ if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) ++ goto unlock; ++ this_cpu_inc(*ibp->rvp.rc_qacks); + qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING; + qp->s_nak_state = qp->r_nak_state; + qp->s_ack_psn = qp->r_ack_psn; +@@ -899,6 +901,7 @@ queue_ack: + + /* Schedule the send tasklet. */ + hfi1_schedule_send(qp); ++unlock: + spin_unlock_irqrestore(&qp->s_lock, flags); + } + diff --git a/queue-4.7/mei-amthif-fix-deadlock-in-initialization-during-a-reset.patch b/queue-4.7/mei-amthif-fix-deadlock-in-initialization-during-a-reset.patch new file mode 100644 index 00000000000..21b93562b4e --- /dev/null +++ b/queue-4.7/mei-amthif-fix-deadlock-in-initialization-during-a-reset.patch @@ -0,0 +1,86 @@ +From e728ae271f4cf71218ec06a6daf61b79466cb466 Mon Sep 17 00:00:00 2001 +From: Alexander Usyskin +Date: Tue, 26 Jul 2016 01:06:09 +0300 +Subject: mei: amthif: fix deadlock in initialization during a reset + +From: Alexander Usyskin + +commit e728ae271f4cf71218ec06a6daf61b79466cb466 upstream. + +The device lock was unnecessary obtained in bus rescan work before the +amthif client search. That causes incorrect lock ordering and task +hang: +... +[88004.613213] INFO: task kworker/1:14:21832 blocked for more than 120 seconds. +... +[88004.645934] Workqueue: events mei_cl_bus_rescan_work +... + +The correct lock order is + cl_bus_lock + device_lock + me_clients_rwsem + +Move device_lock into amthif init function that called +after me_clients_rwsem is released. + +This fixes regression introduced by commit: +commit 025fb792bac3 ("mei: split amthif client init from end of clients enumeration") + +Signed-off-by: Alexander Usyskin +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mei/amthif.c | 12 +++++++++--- + drivers/misc/mei/bus.c | 2 -- + 2 files changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/misc/mei/amthif.c ++++ b/drivers/misc/mei/amthif.c +@@ -67,8 +67,12 @@ int mei_amthif_host_init(struct mei_devi + struct mei_cl *cl = &dev->iamthif_cl; + int ret; + +- if (mei_cl_is_connected(cl)) +- return 0; ++ mutex_lock(&dev->device_lock); ++ ++ if (mei_cl_is_connected(cl)) { ++ ret = 0; ++ goto out; ++ } + + dev->iamthif_state = MEI_IAMTHIF_IDLE; + +@@ -77,11 +81,13 @@ int mei_amthif_host_init(struct mei_devi + ret = mei_cl_link(cl); + if (ret < 0) { + dev_err(dev->dev, "amthif: failed cl_link %d\n", ret); +- return ret; ++ goto out; + } + + ret = mei_cl_connect(cl, me_cl, NULL); + ++out: ++ mutex_unlock(&dev->device_lock); + return ret; + } + +--- a/drivers/misc/mei/bus.c ++++ b/drivers/misc/mei/bus.c +@@ -983,12 +983,10 @@ void mei_cl_bus_rescan_work(struct work_ + container_of(work, struct mei_device, bus_rescan_work); + struct mei_me_client *me_cl; + +- mutex_lock(&bus->device_lock); + me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid); + if (me_cl) + mei_amthif_host_init(bus, me_cl); + mei_me_cl_put(me_cl); +- mutex_unlock(&bus->device_lock); + + mei_cl_bus_rescan(bus); + } diff --git a/queue-4.7/reiserfs-unlock-superblock-before-calling-reiserfs_quota_on_mount.patch b/queue-4.7/reiserfs-unlock-superblock-before-calling-reiserfs_quota_on_mount.patch new file mode 100644 index 00000000000..a7517ad786d --- /dev/null +++ b/queue-4.7/reiserfs-unlock-superblock-before-calling-reiserfs_quota_on_mount.patch @@ -0,0 +1,109 @@ +From 420902c9d086848a7548c83e0a49021514bd71b7 Mon Sep 17 00:00:00 2001 +From: Mike Galbraith +Date: Mon, 13 Aug 2012 15:21:23 +0200 +Subject: reiserfs: Unlock superblock before calling reiserfs_quota_on_mount() + +From: Mike Galbraith + +commit 420902c9d086848a7548c83e0a49021514bd71b7 upstream. + +If we hold the superblock lock while calling reiserfs_quota_on_mount(), we can +deadlock our own worker - mount blocks kworker/3:2, sleeps forever more. + +crash> ps|grep UN + 715 2 3 ffff880220734d30 UN 0.0 0 0 [kworker/3:2] + 9369 9341 2 ffff88021ffb7560 UN 1.3 493404 123184 Xorg + 9665 9664 3 ffff880225b92ab0 UN 0.0 47368 812 udisks-daemon + 10635 10403 3 ffff880222f22c70 UN 0.0 14904 936 mount +crash> bt ffff880220734d30 +PID: 715 TASK: ffff880220734d30 CPU: 3 COMMAND: "kworker/3:2" + #0 [ffff8802244c3c20] schedule at ffffffff8144584b + #1 [ffff8802244c3cc8] __rt_mutex_slowlock at ffffffff814472b3 + #2 [ffff8802244c3d28] rt_mutex_slowlock at ffffffff814473f5 + #3 [ffff8802244c3dc8] reiserfs_write_lock at ffffffffa05f28fd [reiserfs] + #4 [ffff8802244c3de8] flush_async_commits at ffffffffa05ec91d [reiserfs] + #5 [ffff8802244c3e08] process_one_work at ffffffff81073726 + #6 [ffff8802244c3e68] worker_thread at ffffffff81073eba + #7 [ffff8802244c3ec8] kthread at ffffffff810782e0 + #8 [ffff8802244c3f48] kernel_thread_helper at ffffffff81450064 +crash> rd ffff8802244c3cc8 10 +ffff8802244c3cc8: ffffffff814472b3 ffff880222f23250 .rD.....P2.".... +ffff8802244c3cd8: 0000000000000000 0000000000000286 ................ +ffff8802244c3ce8: ffff8802244c3d30 ffff880220734d80 0=L$.....Ms .... +ffff8802244c3cf8: ffff880222e8f628 0000000000000000 (.."............ +ffff8802244c3d08: 0000000000000000 0000000000000002 ................ +crash> struct rt_mutex ffff880222e8f628 +struct rt_mutex { + wait_lock = { + raw_lock = { + slock = 65537 + } + }, + wait_list = { + node_list = { + next = 0xffff8802244c3d48, + prev = 0xffff8802244c3d48 + } + }, + owner = 0xffff880222f22c71, + save_state = 0 +} +crash> bt 0xffff880222f22c70 +PID: 10635 TASK: ffff880222f22c70 CPU: 3 COMMAND: "mount" + #0 [ffff8802216a9868] schedule at ffffffff8144584b + #1 [ffff8802216a9910] schedule_timeout at ffffffff81446865 + #2 [ffff8802216a99a0] wait_for_common at ffffffff81445f74 + #3 [ffff8802216a9a30] flush_work at ffffffff810712d3 + #4 [ffff8802216a9ab0] schedule_on_each_cpu at ffffffff81074463 + #5 [ffff8802216a9ae0] invalidate_bdev at ffffffff81178aba + #6 [ffff8802216a9af0] vfs_load_quota_inode at ffffffff811a3632 + #7 [ffff8802216a9b50] dquot_quota_on_mount at ffffffff811a375c + #8 [ffff8802216a9b80] finish_unfinished at ffffffffa05dd8b0 [reiserfs] + #9 [ffff8802216a9cc0] reiserfs_fill_super at ffffffffa05de825 [reiserfs] + RIP: 00007f7b9303997a RSP: 00007ffff443c7a8 RFLAGS: 00010202 + RAX: 00000000000000a5 RBX: ffffffff8144ef12 RCX: 00007f7b932e9ee0 + RDX: 00007f7b93d9a400 RSI: 00007f7b93d9a3e0 RDI: 00007f7b93d9a3c0 + RBP: 00007f7b93d9a2c0 R8: 00007f7b93d9a550 R9: 0000000000000001 + R10: ffffffffc0ed040e R11: 0000000000000202 R12: 000000000000040e + R13: 0000000000000000 R14: 00000000c0ed040e R15: 00007ffff443ca20 + ORIG_RAX: 00000000000000a5 CS: 0033 SS: 002b + +Signed-off-by: Mike Galbraith +Acked-by: Frederic Weisbecker +Acked-by: Mike Galbraith +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/super.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -190,7 +190,15 @@ static int remove_save_link_only(struct + static int reiserfs_quota_on_mount(struct super_block *, int); + #endif + +-/* look for uncompleted unlinks and truncates and complete them */ ++/* ++ * Look for uncompleted unlinks and truncates and complete them ++ * ++ * Called with superblock write locked. If quotas are enabled, we have to ++ * release/retake lest we call dquot_quota_on_mount(), proceed to ++ * schedule_on_each_cpu() in invalidate_bdev() and deadlock waiting for the per ++ * cpu worklets to complete flush_async_commits() that in turn wait for the ++ * superblock write lock. ++ */ + static int finish_unfinished(struct super_block *s) + { + INITIALIZE_PATH(path); +@@ -237,7 +245,9 @@ static int finish_unfinished(struct supe + quota_enabled[i] = 0; + continue; + } ++ reiserfs_write_unlock(s); + ret = reiserfs_quota_on_mount(s, i); ++ reiserfs_write_lock(s); + if (ret < 0) + reiserfs_warning(s, "reiserfs-2500", + "cannot turn on journaled " diff --git a/queue-4.7/series b/queue-4.7/series index a64c1f40645..9ee64ae2d21 100644 --- a/queue-4.7/series +++ b/queue-4.7/series @@ -7,3 +7,23 @@ debugfs-introduce-a-public-file_operations-accessor.patch b43-fix-debugfs-crash.patch b43legacy-fix-debugfs-crash.patch carl9170-fix-debugfs-crashes.patch +btrfs-fix-free-space-tree-bitmaps-on-big-endian-systems.patch +btrfs-catch-invalid-free-space-trees.patch +btrfs-assign-error-values-to-the-correct-bio-structs.patch +mei-amthif-fix-deadlock-in-initialization-during-a-reset.patch +drivers-base-dma-mapping-page-align-the-size-when-unmap_kernel_range.patch +ib-hfi1-fix-defered-ack-race-with-qp-destroy.patch +clk-mvebu-fix-setting-unwanted-flags-in-cp110-gate-clock.patch +clk-mvebu-dynamically-allocate-resources-in-armada-cp110-system-controller.patch +fuse-listxattr-verify-xattr-list.patch +fuse-invalidate-dir-dentry-after-chmod.patch +fuse-fix-killing-sid-in-setattr.patch +i40e-avoid-null-pointer-dereference-and-recursive-errors-on-early-pci-error.patch +xfs-change-mailing-list-address.patch +brcmfmac-fix-pmksa-bssid-usage.patch +brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch +brcmfmac-use-correct-skb-freeing-helper-when-deleting-flowring.patch +asoc-nau8825-fix-bug-in-fll-parameter.patch +asoc-intel-atom-add-a-missing-star-in-a-memcpy-call.patch +reiserfs-unlock-superblock-before-calling-reiserfs_quota_on_mount.patch +async_pq_val-fix-dma-memory-leak.patch diff --git a/queue-4.7/xfs-change-mailing-list-address.patch b/queue-4.7/xfs-change-mailing-list-address.patch new file mode 100644 index 00000000000..96a1eab6c6c --- /dev/null +++ b/queue-4.7/xfs-change-mailing-list-address.patch @@ -0,0 +1,35 @@ +From 541d48f05fa1c19a4a968d38df685529e728a20a Mon Sep 17 00:00:00 2001 +From: Dave Chinner +Date: Wed, 14 Sep 2016 07:40:21 +1000 +Subject: xfs: change mailing list address + +From: Dave Chinner + +commit 541d48f05fa1c19a4a968d38df685529e728a20a upstream. + +oss.sgi.com is going away, move contact details over to vger. + +Signed-off-by: Dave Chinner +Signed-off-by: Greg Kroah-Hartman + +--- + MAINTAINERS | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -12620,11 +12620,10 @@ F: arch/x86/xen/*swiotlb* + F: drivers/xen/*swiotlb* + + XFS FILESYSTEM +-P: Silicon Graphics Inc + M: Dave Chinner +-M: xfs@oss.sgi.com +-L: xfs@oss.sgi.com +-W: http://oss.sgi.com/projects/xfs ++M: linux-xfs@vger.kernel.org ++L: linux-xfs@vger.kernel.org ++W: http://xfs.org/ + T: git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git + S: Supported + F: Documentation/filesystems/xfs.txt