--- /dev/null
+From b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Sat, 24 Nov 2018 17:57:05 -0500
+Subject: brcmfmac: Fix out of bounds memory access during fw load
+
+From: Lyude Paul <lyude@redhat.com>
+
+commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b upstream.
+
+I ended up tracking down some rather nasty issues with f2fs (and other
+filesystem modules) constantly crashing on my kernel down to a
+combination of out of bounds memory accesses, one of which was coming
+from brcmfmac during module load:
+
+[ 30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2
+[ 30.894437] ==================================================================
+[ 30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
+[ 30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387
+[ 30.916805]
+[ 30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G O 4.20.0-rc3Lyude-Test+ #19
+[ 30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018
+[ 30.935964] Workqueue: events brcmf_driver_register [brcmfmac]
+[ 30.941641] Call trace:
+[ 30.944058] dump_backtrace+0x0/0x3e8
+[ 30.947676] show_stack+0x14/0x20
+[ 30.950968] dump_stack+0x130/0x1c4
+[ 30.954406] print_address_description+0x60/0x25c
+[ 30.959066] kasan_report+0x1b4/0x368
+[ 30.962683] __asan_report_load1_noabort+0x18/0x20
+[ 30.967547] brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac]
+[ 30.967639] brcmf_sdio_probe+0x163c/0x2050 [brcmfmac]
+[ 30.978035] brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac]
+[ 30.983254] sdio_bus_probe+0x190/0x398
+[ 30.983270] really_probe+0x2a0/0xa70
+[ 30.983296] driver_probe_device+0x1b4/0x2d8
+[ 30.994901] __driver_attach+0x200/0x280
+[ 30.994914] bus_for_each_dev+0x10c/0x1a8
+[ 30.994925] driver_attach+0x38/0x50
+[ 30.994935] bus_add_driver+0x330/0x608
+[ 30.994953] driver_register+0x140/0x388
+[ 31.013965] sdio_register_driver+0x74/0xa0
+[ 31.014076] brcmf_sdio_register+0x14/0x60 [brcmfmac]
+[ 31.023177] brcmf_driver_register+0xc/0x18 [brcmfmac]
+[ 31.023209] process_one_work+0x654/0x1080
+[ 31.032266] worker_thread+0x4f0/0x1308
+[ 31.032286] kthread+0x2a8/0x320
+[ 31.039254] ret_from_fork+0x10/0x1c
+[ 31.039269]
+[ 31.044226] The buggy address belongs to the variable:
+[ 31.044351] brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac]
+[ 31.055601]
+[ 31.057031] Memory state around the buggy address:
+[ 31.061800] ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
+[ 31.068983] ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
+[ 31.068999] ^
+[ 31.069017] ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 31.096521] ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
+[ 31.096528] ==================================================================
+[ 31.096533] Disabling lock debugging due to kernel taint
+
+It appears that when trying to determine the length of the string in the
+alternate firmware path, we make the mistake of not handling the case
+where the firmware path is empty correctly. Since strlen(mp_path) can
+return 0, we'll end up accessing mp_path[-1] when the firmware_path
+isn't provided through the module arguments.
+
+So, fix this by just setting the end char to '\0' by default, and only
+changing it if we have a non-zero length. Additionally, use strnlen()
+with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe.
+
+Fixes: 2baa3aaee27f ("brcmfmac: introduce brcmf_fw_alloc_request() function")
+Cc: Hante Meuleman <hante.meuleman@broadcom.com>
+Cc: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Cc: Franky Lin <franky.lin@broadcom.com>
+Cc: Arend van Spriel <arend.vanspriel@broadcom.com>
+Cc: Kalle Valo <kvalo@codeaurora.org>
+Cc: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Cc: Himanshu Jha <himanshujha199640@gmail.com>
+Cc: Dan Haab <dhaab@luxul.com>
+Cc: Jia-Shyr Chuang <saint.chuang@cypress.com>
+Cc: Ian Molton <ian@mnementh.co.uk>
+Cc: <stable@vger.kernel.org> # v4.17+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -641,8 +641,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chi
+ struct brcmf_fw_request *fwreq;
+ char chipname[12];
+ const char *mp_path;
++ size_t mp_path_len;
+ u32 i, j;
+- char end;
++ char end = '\0';
+ size_t reqsz;
+
+ for (i = 0; i < table_size; i++) {
+@@ -667,7 +668,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi
+ mapping_table[i].fw_base, chipname);
+
+ mp_path = brcmf_mp_global.firmware_path;
+- end = mp_path[strlen(mp_path) - 1];
++ mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN);
++ if (mp_path_len)
++ end = mp_path[mp_path_len - 1];
++
+ fwreq->n_items = n_fwnames;
+
+ for (j = 0; j < n_fwnames; j++) {
--- /dev/null
+From 8c892df41500469729e0d662816300196e4f463d Mon Sep 17 00:00:00 2001
+From: Stijn Tintel <stijn@linux-ipv6.be>
+Date: Tue, 4 Dec 2018 20:29:05 +0200
+Subject: brcmfmac: fix roamoff=1 modparam
+
+From: Stijn Tintel <stijn@linux-ipv6.be>
+
+commit 8c892df41500469729e0d662816300196e4f463d upstream.
+
+When the update_connect_param callback is set, nl80211 expects the flag
+WIPHY_FLAG_SUPPORTS_FW_ROAM to be set as well. However, this flag is
+only set when modparam roamoff=0, while the callback is set
+unconditionally. Since commit 7f9a3e150ec7 this causes a warning in
+wiphy_register, which breaks brcmfmac.
+
+Disable the update_connect_param callback when roamoff=0 to fix this.
+
+Fixes: 7f9a3e150ec7 ("nl80211: Update ERP info using NL80211_CMD_UPDATE_CONNECT_PARAMS")
+Cc: Stable <stable@vger.kernel.org> # 4.19+
+Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
+Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 11 +++++++++--
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
+ 3 files changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -5188,10 +5188,17 @@ static struct cfg80211_ops brcmf_cfg8021
+ .del_pmk = brcmf_cfg80211_del_pmk,
+ };
+
+-struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
++struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
+ {
+- return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
++ struct cfg80211_ops *ops;
++
++ ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
+ GFP_KERNEL);
++
++ if (ops && settings->roamoff)
++ ops->update_connect_params = NULL;
++
++ return ops;
+ }
+
+ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+@@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
+ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
+ s32 brcmf_cfg80211_up(struct net_device *ndev);
+ s32 brcmf_cfg80211_down(struct net_device *ndev);
+-struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
++struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings);
+ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
+
+ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1130,7 +1130,7 @@ int brcmf_attach(struct device *dev, str
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+- ops = brcmf_cfg80211_get_ops();
++ ops = brcmf_cfg80211_get_ops(settings);
+ if (!ops)
+ return -ENOMEM;
+
--- /dev/null
+From 05c49e6bc1e8866ecfd674ebeeb58cdbff9145c2 Mon Sep 17 00:00:00 2001
+From: Anand Jain <anand.jain@oracle.com>
+Date: Sun, 11 Nov 2018 22:22:18 +0800
+Subject: btrfs: dev-replace: go back to suspend state if another EXCL_OP is running
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit 05c49e6bc1e8866ecfd674ebeeb58cdbff9145c2 upstream.
+
+In a secnario where balance and replace co-exists as below,
+
+ - start balance
+ - pause balance
+ - start replace
+ - reboot
+
+and when system restarts, balance resumes first. Then the replace is
+attempted to restart but will fail as the EXCL_OP lock is already held
+by the balance. If so place the replace state back to
+BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state.
+
+Fixes: 010a47bde9420 ("btrfs: add proper safety check before resuming dev-replace")
+CC: stable@vger.kernel.org # 4.18+
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/dev-replace.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/btrfs/dev-replace.c
++++ b/fs/btrfs/dev-replace.c
+@@ -900,6 +900,10 @@ int btrfs_resume_dev_replace_async(struc
+ * dev-replace to start anyway.
+ */
+ if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
++ btrfs_dev_replace_write_lock(dev_replace);
++ dev_replace->replace_state =
++ BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED;
++ btrfs_dev_replace_write_unlock(dev_replace);
+ btrfs_info(fs_info,
+ "cannot resume dev-replace, other exclusive operation running");
+ return 0;
--- /dev/null
+From 0d228ece59a35a9b9e8ff0d40653234a6d90f61e Mon Sep 17 00:00:00 2001
+From: Anand Jain <anand.jain@oracle.com>
+Date: Sun, 11 Nov 2018 22:22:17 +0800
+Subject: btrfs: dev-replace: go back to suspended state if target device is missing
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit 0d228ece59a35a9b9e8ff0d40653234a6d90f61e upstream.
+
+At the time of forced unmount we place the running replace to
+BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state, so when the system comes
+back and expect the target device is missing.
+
+Then let the replace state continue to be in
+BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED state instead of
+BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED as there isn't any matching scrub
+running as part of replace.
+
+Fixes: e93c89c1aaaa ("Btrfs: add new sources for device replace code")
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/dev-replace.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/dev-replace.c
++++ b/fs/btrfs/dev-replace.c
+@@ -887,6 +887,8 @@ int btrfs_resume_dev_replace_async(struc
+ "cannot continue dev_replace, tgtdev is missing");
+ btrfs_info(fs_info,
+ "you may cancel the operation after 'mount -o degraded'");
++ dev_replace->replace_state =
++ BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED;
+ btrfs_dev_replace_write_unlock(dev_replace);
+ return 0;
+ }
--- /dev/null
+From 41bd60676923822de1df2c50b3f9a10171f4338a Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 28 Nov 2018 14:54:28 +0000
+Subject: Btrfs: fix fsync of files with multiple hard links in new directories
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 41bd60676923822de1df2c50b3f9a10171f4338a upstream.
+
+The log tree has a long standing problem that when a file is fsync'ed we
+only check for new ancestors, created in the current transaction, by
+following only the hard link for which the fsync was issued. We follow the
+ancestors using the VFS' dget_parent() API. This means that if we create a
+new link for a file in a directory that is new (or in an any other new
+ancestor directory) and then fsync the file using an old hard link, we end
+up not logging the new ancestor, and on log replay that new hard link and
+ancestor do not exist. In some cases, involving renames, the file will not
+exist at all.
+
+Example:
+
+ mkfs.btrfs -f /dev/sdb
+ mount /dev/sdb /mnt
+
+ mkdir /mnt/A
+ touch /mnt/foo
+ ln /mnt/foo /mnt/A/bar
+ xfs_io -c fsync /mnt/foo
+
+ <power failure>
+
+In this example after log replay only the hard link named 'foo' exists
+and directory A does not exist, which is unexpected. In other major linux
+filesystems, such as ext4, xfs and f2fs for example, both hard links exist
+and so does directory A after mounting again the filesystem.
+
+Checking if any new ancestors are new and need to be logged was added in
+2009 by commit 12fcfd22fe5b ("Btrfs: tree logging unlink/rename fixes"),
+however only for the ancestors of the hard link (dentry) for which the
+fsync was issued, instead of checking for all ancestors for all of the
+inode's hard links.
+
+So fix this by tracking the id of the last transaction where a hard link
+was created for an inode and then on fsync fallback to a full transaction
+commit when an inode has more than one hard link and at least one new hard
+link was created in the current transaction. This is the simplest solution
+since this is not a common use case (adding frequently hard links for
+which there's an ancestor created in the current transaction and then
+fsync the file). In case it ever becomes a common use case, a solution
+that consists of iterating the fs/subvol btree for each hard link and
+check if any ancestor is new, could be implemented.
+
+This solves many unexpected scenarios reported by Jayashree Mohan and
+Vijay Chidambaram, and for which there is a new test case for fstests
+under review.
+
+Fixes: 12fcfd22fe5b ("Btrfs: tree logging unlink/rename fixes")
+CC: stable@vger.kernel.org # 4.4+
+Reported-by: Vijay Chidambaram <vvijay03@gmail.com>
+Reported-by: Jayashree Mohan <jayashree2912@gmail.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/btrfs_inode.h | 6 ++++++
+ fs/btrfs/inode.c | 17 +++++++++++++++++
+ fs/btrfs/tree-log.c | 16 ++++++++++++++++
+ 3 files changed, 39 insertions(+)
+
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -147,6 +147,12 @@ struct btrfs_inode {
+ u64 last_unlink_trans;
+
+ /*
++ * Track the transaction id of the last transaction used to create a
++ * hard link for the inode. This is used by the log tree (fsync).
++ */
++ u64 last_link_trans;
++
++ /*
+ * Number of bytes outstanding that are going to need csums. This is
+ * used in ENOSPC accounting.
+ */
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3689,6 +3689,21 @@ cache_index:
+ * inode is not a directory, logging its parent unnecessarily.
+ */
+ BTRFS_I(inode)->last_unlink_trans = BTRFS_I(inode)->last_trans;
++ /*
++ * Similar reasoning for last_link_trans, needs to be set otherwise
++ * for a case like the following:
++ *
++ * mkdir A
++ * touch foo
++ * ln foo A/bar
++ * echo 2 > /proc/sys/vm/drop_caches
++ * fsync foo
++ * <power failure>
++ *
++ * Would result in link bar and directory A not existing after the power
++ * failure.
++ */
++ BTRFS_I(inode)->last_link_trans = BTRFS_I(inode)->last_trans;
+
+ path->slots[0]++;
+ if (inode->i_nlink != 1 ||
+@@ -6647,6 +6662,7 @@ static int btrfs_link(struct dentry *old
+ if (err)
+ goto fail;
+ }
++ BTRFS_I(inode)->last_link_trans = trans->transid;
+ d_instantiate(dentry, inode);
+ ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent,
+ true, NULL);
+@@ -9175,6 +9191,7 @@ struct inode *btrfs_alloc_inode(struct s
+ ei->index_cnt = (u64)-1;
+ ei->dir_index = 0;
+ ei->last_unlink_trans = 0;
++ ei->last_link_trans = 0;
+ ei->last_log_commit = 0;
+
+ spin_lock_init(&ei->lock);
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -5781,6 +5781,22 @@ static int btrfs_log_inode_parent(struct
+ goto end_trans;
+ }
+
++ /*
++ * If a new hard link was added to the inode in the current transaction
++ * and its link count is now greater than 1, we need to fallback to a
++ * transaction commit, otherwise we can end up not logging all its new
++ * parents for all the hard links. Here just from the dentry used to
++ * fsync, we can not visit the ancestor inodes for all the other hard
++ * links to figure out if any is new, so we fallback to a transaction
++ * commit (instead of adding a lot of complexity of scanning a btree,
++ * since this scenario is not a common use case).
++ */
++ if (inode->vfs_inode.i_nlink > 1 &&
++ inode->last_link_trans > last_committed) {
++ ret = -EMLINK;
++ goto end_trans;
++ }
++
+ while (1) {
+ if (!parent || d_really_is_negative(parent) || sb != parent->d_sb)
+ break;
--- /dev/null
+From 0568e82dbe2510fc1fa664f58e5c997d3f1e649e Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Fri, 30 Nov 2018 11:52:14 -0500
+Subject: btrfs: run delayed items before dropping the snapshot
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit 0568e82dbe2510fc1fa664f58e5c997d3f1e649e upstream.
+
+With my delayed refs patches in place we started seeing a large amount
+of aborts in __btrfs_free_extent:
+
+ BTRFS error (device sdb1): unable to find ref byte nr 91947008 parent 0 root 35964 owner 1 offset 0
+ Call Trace:
+ ? btrfs_merge_delayed_refs+0xaf/0x340
+ __btrfs_run_delayed_refs+0x6ea/0xfc0
+ ? btrfs_set_path_blocking+0x31/0x60
+ btrfs_run_delayed_refs+0xeb/0x180
+ btrfs_commit_transaction+0x179/0x7f0
+ ? btrfs_check_space_for_delayed_refs+0x30/0x50
+ ? should_end_transaction.isra.19+0xe/0x40
+ btrfs_drop_snapshot+0x41c/0x7c0
+ btrfs_clean_one_deleted_snapshot+0xb5/0xd0
+ cleaner_kthread+0xf6/0x120
+ kthread+0xf8/0x130
+ ? btree_invalidatepage+0x90/0x90
+ ? kthread_bind+0x10/0x10
+ ret_from_fork+0x35/0x40
+
+This was because btrfs_drop_snapshot depends on the root not being
+modified while it's dropping the snapshot. It will unlock the root node
+(and really every node) as it walks down the tree, only to re-lock it
+when it needs to do something. This is a problem because if we modify
+the tree we could cow a block in our path, which frees our reference to
+that block. Then once we get back to that shared block we'll free our
+reference to it again, and get ENOENT when trying to lookup our extent
+reference to that block in __btrfs_free_extent.
+
+This is ultimately happening because we have delayed items left to be
+processed for our deleted snapshot _after_ all of the inodes are closed
+for the snapshot. We only run the delayed inode item if we're deleting
+the inode, and even then we do not run the delayed insertions or delayed
+removals. These can be run at any point after our final inode does its
+last iput, which is what triggers the snapshot deletion. We can end up
+with the snapshot deletion happening and then have the delayed items run
+on that file system, resulting in the above problem.
+
+This problem has existed forever, however my patches made it much easier
+to hit as I wake up the cleaner much more often to deal with delayed
+iputs, which made us more likely to start the snapshot dropping work
+before the transaction commits, which is when the delayed items would
+generally be run. Before, generally speaking, we would run the delayed
+items, commit the transaction, and wakeup the cleaner thread to start
+deleting snapshots, which means we were less likely to hit this problem.
+You could still hit it if you had multiple snapshots to be deleted and
+ended up with lots of delayed items, but it was definitely harder.
+
+Fix for now by simply running all the delayed items before starting to
+drop the snapshot. We could make this smarter in the future by making
+the delayed items per-root, and then simply drop any delayed items for
+roots that we are going to delete. But for now just a quick and easy
+solution is the safest.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -8911,6 +8911,10 @@ int btrfs_drop_snapshot(struct btrfs_roo
+ goto out_free;
+ }
+
++ err = btrfs_run_delayed_items(trans);
++ if (err)
++ goto out_end_trans;
++
+ if (block_rsv)
+ trans->block_rsv = block_rsv;
+
--- /dev/null
+From be6821f82c3cc36e026f5afd10249988852b35ea Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Tue, 11 Dec 2018 10:19:45 +0000
+Subject: Btrfs: send, fix race with transaction commits that create snapshots
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit be6821f82c3cc36e026f5afd10249988852b35ea upstream.
+
+If we create a snapshot of a snapshot currently being used by a send
+operation, we can end up with send failing unexpectedly (returning
+-ENOENT error to user space for example). The following diagram shows
+how this happens.
+
+ CPU 1 CPU2 CPU3
+
+ btrfs_ioctl_send()
+ (...)
+ create_snapshot()
+ -> creates snapshot of a
+ root used by the send
+ task
+ btrfs_commit_transaction()
+ create_pending_snapshot()
+ __get_inode_info()
+ btrfs_search_slot()
+ btrfs_search_slot_get_root()
+ down_read commit_root_sem
+
+ get reference on eb of the
+ commit root
+ -> eb with bytenr == X
+
+ up_read commit_root_sem
+
+ btrfs_cow_block(root node)
+ btrfs_free_tree_block()
+ -> creates delayed ref to
+ free the extent
+
+ btrfs_run_delayed_refs()
+ -> runs the delayed ref,
+ adds extent to
+ fs_info->pinned_extents
+
+ btrfs_finish_extent_commit()
+ unpin_extent_range()
+ -> marks extent as free
+ in the free space cache
+
+ transaction commit finishes
+
+ btrfs_start_transaction()
+ (...)
+ btrfs_cow_block()
+ btrfs_alloc_tree_block()
+ btrfs_reserve_extent()
+ -> allocates extent at
+ bytenr == X
+ btrfs_init_new_buffer(bytenr X)
+ btrfs_find_create_tree_block()
+ alloc_extent_buffer(bytenr X)
+ find_extent_buffer(bytenr X)
+ -> returns existing eb,
+ which the send task got
+
+ (...)
+ -> modifies content of the
+ eb with bytenr == X
+
+ -> uses an eb that now
+ belongs to some other
+ tree and no more matches
+ the commit root of the
+ snapshot, resuts will be
+ unpredictable
+
+The consequences of this race can be various, and can lead to searches in
+the commit root performed by the send task failing unexpectedly (unable to
+find inode items, returning -ENOENT to user space, for example) or not
+failing because an inode item with the same number was added to the tree
+that reused the metadata extent, in which case send can behave incorrectly
+in the worst case or just fail later for some reason.
+
+Fix this by performing a copy of the commit root's extent buffer when doing
+a search in the context of a send operation.
+
+CC: stable@vger.kernel.org # 4.4.x: 1fc28d8e2e9: Btrfs: move get root out of btrfs_search_slot to a helper
+CC: stable@vger.kernel.org # 4.4.x: f9ddfd0592a: Btrfs: remove unused check of skip_locking
+CC: stable@vger.kernel.org # 4.4.x
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ctree.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -2624,14 +2624,27 @@ static struct extent_buffer *btrfs_searc
+ root_lock = BTRFS_READ_LOCK;
+
+ if (p->search_commit_root) {
+- /* The commit roots are read only so we always do read locks */
+- if (p->need_commit_sem)
++ /*
++ * The commit roots are read only so we always do read locks,
++ * and we always must hold the commit_root_sem when doing
++ * searches on them, the only exception is send where we don't
++ * want to block transaction commits for a long time, so
++ * we need to clone the commit root in order to avoid races
++ * with transaction commits that create a snapshot of one of
++ * the roots used by a send operation.
++ */
++ if (p->need_commit_sem) {
+ down_read(&fs_info->commit_root_sem);
+- b = root->commit_root;
+- extent_buffer_get(b);
+- level = btrfs_header_level(b);
+- if (p->need_commit_sem)
++ b = btrfs_clone_extent_buffer(root->commit_root);
+ up_read(&fs_info->commit_root_sem);
++ if (!b)
++ return ERR_PTR(-ENOMEM);
++
++ } else {
++ b = root->commit_root;
++ extent_buffer_get(b);
++ }
++ level = btrfs_header_level(b);
+ /*
+ * Ensure that all callers have set skip_locking when
+ * p->search_commit_root = 1.
+@@ -2757,6 +2770,10 @@ int btrfs_search_slot(struct btrfs_trans
+ again:
+ prev_cmp = -1;
+ b = btrfs_search_slot_get_root(root, p, write_lock_level);
++ if (IS_ERR(b)) {
++ ret = PTR_ERR(b);
++ goto done;
++ }
+
+ while (b) {
+ level = btrfs_header_level(b);
--- /dev/null
+From 27a7ff554e8d349627a90bda275c527b7348adae Mon Sep 17 00:00:00 2001
+From: Lu Fengqi <lufq.fnst@cn.fujitsu.com>
+Date: Thu, 29 Nov 2018 17:31:32 +0800
+Subject: btrfs: skip file_extent generation check for free_space_inode in run_delalloc_nocow
+
+From: Lu Fengqi <lufq.fnst@cn.fujitsu.com>
+
+commit 27a7ff554e8d349627a90bda275c527b7348adae upstream.
+
+The test case btrfs/001 with inode_cache mount option will encounter the
+following warning:
+
+ WARNING: CPU: 1 PID: 23700 at fs/btrfs/inode.c:956 cow_file_range.isra.19+0x32b/0x430 [btrfs]
+ CPU: 1 PID: 23700 Comm: btrfs Kdump: loaded Tainted: G W O 4.20.0-rc4-custom+ #30
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+ RIP: 0010:cow_file_range.isra.19+0x32b/0x430 [btrfs]
+ Call Trace:
+ ? free_extent_buffer+0x46/0x90 [btrfs]
+ run_delalloc_nocow+0x455/0x900 [btrfs]
+ btrfs_run_delalloc_range+0x1a7/0x360 [btrfs]
+ writepage_delalloc+0xf9/0x150 [btrfs]
+ __extent_writepage+0x125/0x3e0 [btrfs]
+ extent_write_cache_pages+0x1b6/0x3e0 [btrfs]
+ ? __wake_up_common_lock+0x63/0xc0
+ extent_writepages+0x50/0x80 [btrfs]
+ do_writepages+0x41/0xd0
+ ? __filemap_fdatawrite_range+0x9e/0xf0
+ __filemap_fdatawrite_range+0xbe/0xf0
+ btrfs_fdatawrite_range+0x1b/0x50 [btrfs]
+ __btrfs_write_out_cache+0x42c/0x480 [btrfs]
+ btrfs_write_out_ino_cache+0x84/0xd0 [btrfs]
+ btrfs_save_ino_cache+0x551/0x660 [btrfs]
+ commit_fs_roots+0xc5/0x190 [btrfs]
+ btrfs_commit_transaction+0x2bf/0x8d0 [btrfs]
+ btrfs_mksubvol+0x48d/0x4d0 [btrfs]
+ btrfs_ioctl_snap_create_transid+0x170/0x180 [btrfs]
+ btrfs_ioctl_snap_create_v2+0x124/0x180 [btrfs]
+ btrfs_ioctl+0x123f/0x3030 [btrfs]
+
+The file extent generation of the free space inode is equal to the last
+snapshot of the file root, so the inode will be passed to cow_file_rage.
+But the inode was created and its extents were preallocated in
+btrfs_save_ino_cache, there are no cow copies on disk.
+
+The preallocated extent is not yet in the extent tree, and
+btrfs_cross_ref_exist will ignore the -ENOENT returned by
+check_committed_ref, so we can directly write the inode to the disk.
+
+Fixes: 78d4295b1eee ("btrfs: lift some btrfs_cross_ref_exist checks in nocow path")
+CC: stable@vger.kernel.org # 4.18+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Lu Fengqi <lufq.fnst@cn.fujitsu.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1373,7 +1373,8 @@ next_slot:
+ * Do the same check as in btrfs_cross_ref_exist but
+ * without the unnecessary search.
+ */
+- if (btrfs_file_extent_generation(leaf, fi) <=
++ if (!nolock &&
++ btrfs_file_extent_generation(leaf, fi) <=
+ btrfs_root_last_snapshot(&root->root_item))
+ goto out_check;
+ if (extent_type == BTRFS_FILE_EXTENT_REG && !force)
--- /dev/null
+From eafb27fa5283599ce6c5492ea18cf636a28222bb Mon Sep 17 00:00:00 2001
+From: Macpaul Lin <macpaul.lin@mediatek.com>
+Date: Wed, 19 Dec 2018 12:11:03 +0800
+Subject: cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader.
+
+From: Macpaul Lin <macpaul.lin@mediatek.com>
+
+commit eafb27fa5283599ce6c5492ea18cf636a28222bb upstream.
+
+Mediatek Preloader is a proprietary embedded boot loader for loading
+Little Kernel and Linux into device DRAM.
+
+This boot loader also handle firmware update. Mediatek Preloader will be
+enumerated as a virtual COM port when the device is connected to Windows
+or Linux OS via CDC-ACM class driver. When the USB enumeration has been
+done, Mediatek Preloader will send out handshake command "READY" to PC
+actively instead of waiting command from the download tool.
+
+Since Linux 4.12, the commit "tty: reset termios state on device
+registration" (93857edd9829e144acb6c7e72d593f6e01aead66) causes Mediatek
+Preloader receiving some abnoraml command like "READYXX" as it sent.
+This will be recognized as an incorrect response. The behavior change
+also causes the download handshake fail. This change only affects
+subsequent connects if the reconnected device happens to get the same minor
+number.
+
+By disabling the ECHO termios flag could avoid this problem. However, it
+cannot be done by user space configuration when download tool open
+/dev/ttyACM0. This is because the device running Mediatek Preloader will
+send handshake command "READY" immediately once the CDC-ACM driver is
+ready.
+
+This patch wants to fix above problem by introducing "DISABLE_ECHO"
+property in driver_info. When Mediatek Preloader is connected, the
+CDC-ACM driver could disable ECHO flag in termios to avoid the problem.
+
+Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 10 ++++++++++
+ drivers/usb/class/cdc-acm.h | 1 +
+ 2 files changed, 11 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -581,6 +581,13 @@ static int acm_tty_install(struct tty_dr
+ if (retval)
+ goto error_init_termios;
+
++ /*
++ * Suppress initial echoing for some devices which might send data
++ * immediately after acm driver has been installed.
++ */
++ if (acm->quirks & DISABLE_ECHO)
++ tty->termios.c_lflag &= ~ECHO;
++
+ tty->driver_data = acm;
+
+ return 0;
+@@ -1672,6 +1679,9 @@ static const struct usb_device_id acm_id
+ { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
++ { USB_DEVICE(0x0e8d, 0x2000), /* MediaTek Inc Preloader */
++ .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */
++ },
+ { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */
+ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+ },
+--- a/drivers/usb/class/cdc-acm.h
++++ b/drivers/usb/class/cdc-acm.h
+@@ -140,3 +140,4 @@ struct acm {
+ #define QUIRK_CONTROL_LINE_STATE BIT(6)
+ #define CLEAR_HALT_CONDITIONS BIT(7)
+ #define SEND_ZERO_PACKET BIT(8)
++#define DISABLE_ECHO BIT(9)
--- /dev/null
+From e9d81a1bc2c48ea9782e3e8b53875f419766ef47 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Thu, 8 Nov 2018 12:15:15 -0800
+Subject: cgroup: fix CSS_TASK_ITER_PROCS
+
+From: Tejun Heo <tj@kernel.org>
+
+commit e9d81a1bc2c48ea9782e3e8b53875f419766ef47 upstream.
+
+CSS_TASK_ITER_PROCS implements process-only iteration by making
+css_task_iter_advance() skip tasks which aren't threadgroup leaders;
+however, when an iteration is started css_task_iter_start() calls the
+inner helper function css_task_iter_advance_css_set() instead of
+css_task_iter_advance(). As the helper doesn't have the skip logic,
+when the first task to visit is a non-leader thread, it doesn't get
+skipped correctly as shown in the following example.
+
+ # ps -L 2030
+ PID LWP TTY STAT TIME COMMAND
+ 2030 2030 pts/0 Sl+ 0:00 ./test-thread
+ 2030 2031 pts/0 Sl+ 0:00 ./test-thread
+ # mkdir -p /sys/fs/cgroup/x/a/b
+ # echo threaded > /sys/fs/cgroup/x/a/cgroup.type
+ # echo threaded > /sys/fs/cgroup/x/a/b/cgroup.type
+ # echo 2030 > /sys/fs/cgroup/x/a/cgroup.procs
+ # cat /sys/fs/cgroup/x/a/cgroup.threads
+ 2030
+ 2031
+ # cat /sys/fs/cgroup/x/cgroup.procs
+ 2030
+ # echo 2030 > /sys/fs/cgroup/x/a/b/cgroup.threads
+ # cat /sys/fs/cgroup/x/cgroup.procs
+ 2031
+ 2030
+
+The last read of cgroup.procs is incorrectly showing non-leader 2031
+in cgroup.procs output.
+
+This can be fixed by updating css_task_iter_advance() to handle the
+first advance and css_task_iters_tart() to call
+css_task_iter_advance() instead of the inner helper. After the fix,
+the same commands result in the following (correct) result:
+
+ # ps -L 2062
+ PID LWP TTY STAT TIME COMMAND
+ 2062 2062 pts/0 Sl+ 0:00 ./test-thread
+ 2062 2063 pts/0 Sl+ 0:00 ./test-thread
+ # mkdir -p /sys/fs/cgroup/x/a/b
+ # echo threaded > /sys/fs/cgroup/x/a/cgroup.type
+ # echo threaded > /sys/fs/cgroup/x/a/b/cgroup.type
+ # echo 2062 > /sys/fs/cgroup/x/a/cgroup.procs
+ # cat /sys/fs/cgroup/x/a/cgroup.threads
+ 2062
+ 2063
+ # cat /sys/fs/cgroup/x/cgroup.procs
+ 2062
+ # echo 2062 > /sys/fs/cgroup/x/a/b/cgroup.threads
+ # cat /sys/fs/cgroup/x/cgroup.procs
+ 2062
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: "Michael Kerrisk (man-pages)" <mtk.manpages@gmail.com>
+Fixes: 8cfd8147df67 ("cgroup: implement cgroup v2 thread support")
+Cc: stable@vger.kernel.org # v4.14+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/cgroup/cgroup.c | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -4186,20 +4186,25 @@ static void css_task_iter_advance(struct
+
+ lockdep_assert_held(&css_set_lock);
+ repeat:
+- /*
+- * Advance iterator to find next entry. cset->tasks is consumed
+- * first and then ->mg_tasks. After ->mg_tasks, we move onto the
+- * next cset.
+- */
+- next = it->task_pos->next;
+-
+- if (next == it->tasks_head)
+- next = it->mg_tasks_head->next;
+-
+- if (next == it->mg_tasks_head)
++ if (it->task_pos) {
++ /*
++ * Advance iterator to find next entry. cset->tasks is
++ * consumed first and then ->mg_tasks. After ->mg_tasks,
++ * we move onto the next cset.
++ */
++ next = it->task_pos->next;
++
++ if (next == it->tasks_head)
++ next = it->mg_tasks_head->next;
++
++ if (next == it->mg_tasks_head)
++ css_task_iter_advance_css_set(it);
++ else
++ it->task_pos = next;
++ } else {
++ /* called from start, proceed to the first cset */
+ css_task_iter_advance_css_set(it);
+- else
+- it->task_pos = next;
++ }
+
+ /* if PROCS, skip over tasks which aren't group leaders */
+ if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos &&
+@@ -4239,7 +4244,7 @@ void css_task_iter_start(struct cgroup_s
+
+ it->cset_head = it->cset_pos;
+
+- css_task_iter_advance_css_set(it);
++ css_task_iter_advance(it);
+
+ spin_unlock_irq(&css_set_lock);
+ }
--- /dev/null
+From 8b19faf6fae2867e2c177212c541e8ae36aa4d32 Mon Sep 17 00:00:00 2001
+From: Johan Jonker <jbx9999@hotmail.com>
+Date: Sat, 3 Nov 2018 23:54:13 +0100
+Subject: clk: rockchip: fix typo in rk3188 spdif_frac parent
+
+From: Johan Jonker <jbx9999@hotmail.com>
+
+commit 8b19faf6fae2867e2c177212c541e8ae36aa4d32 upstream.
+
+Fix typo in common_clk_branches.
+Make spdif_pre parent of spdif_frac.
+
+Fixes: 667464208989 ("clk: rockchip: include downstream muxes into fractional dividers")
+Cc: stable@vger.kernel.org
+Signed-off-by: Johan Jonker <jbx9999@hotmail.com>
+Acked-by: Elaine Zhang <zhangqing@rock-chips.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/rockchip/clk-rk3188.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/rockchip/clk-rk3188.c
++++ b/drivers/clk/rockchip/clk-rk3188.c
+@@ -382,7 +382,7 @@ static struct rockchip_clk_branch common
+ COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
+ RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
+ RK2928_CLKGATE_CON(0), 13, GFLAGS),
+- COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pll", CLK_SET_RATE_PARENT,
++ COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT,
+ RK2928_CLKSEL_CON(9), 0,
+ RK2928_CLKGATE_CON(0), 14, GFLAGS,
+ &common_spdif_fracmux),
--- /dev/null
+From 65b6657672388b72822e0367f06d41c1e3ffb5bb Mon Sep 17 00:00:00 2001
+From: Jernej Skrabec <jernej.skrabec@siol.net>
+Date: Sun, 4 Nov 2018 19:26:40 +0100
+Subject: clk: sunxi-ng: Use u64 for calculation of NM rate
+
+From: Jernej Skrabec <jernej.skrabec@siol.net>
+
+commit 65b6657672388b72822e0367f06d41c1e3ffb5bb upstream.
+
+Allwinner H6 SoC has multiplier N range between 1 and 254. Since parent
+rate is 24MHz, intermediate result when calculating final rate easily
+overflows 32 bit variable.
+
+Because of that, introduce function for calculating clock rate which
+uses 64 bit variable for intermediate result.
+
+Fixes: 6174a1e24b0d ("clk: sunxi-ng: Add N-M-factor clock support")
+Fixes: ee28648cb2b4 ("clk: sunxi-ng: Remove the use of rational computations")
+
+CC: <stable@vger.kernel.org>
+Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
+Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/sunxi-ng/ccu_nm.c | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/clk/sunxi-ng/ccu_nm.c
++++ b/drivers/clk/sunxi-ng/ccu_nm.c
+@@ -19,6 +19,17 @@ struct _ccu_nm {
+ unsigned long m, min_m, max_m;
+ };
+
++static unsigned long ccu_nm_calc_rate(unsigned long parent,
++ unsigned long n, unsigned long m)
++{
++ u64 rate = parent;
++
++ rate *= n;
++ do_div(rate, m);
++
++ return rate;
++}
++
+ static void ccu_nm_find_best(unsigned long parent, unsigned long rate,
+ struct _ccu_nm *nm)
+ {
+@@ -28,7 +39,8 @@ static void ccu_nm_find_best(unsigned lo
+
+ for (_n = nm->min_n; _n <= nm->max_n; _n++) {
+ for (_m = nm->min_m; _m <= nm->max_m; _m++) {
+- unsigned long tmp_rate = parent * _n / _m;
++ unsigned long tmp_rate = ccu_nm_calc_rate(parent,
++ _n, _m);
+
+ if (tmp_rate > rate)
+ continue;
+@@ -100,7 +112,7 @@ static unsigned long ccu_nm_recalc_rate(
+ if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm))
+ rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n);
+ else
+- rate = parent_rate * n / m;
++ rate = ccu_nm_calc_rate(parent_rate, n, m);
+
+ if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+ rate /= nm->fixed_post_div;
+@@ -142,7 +154,7 @@ static long ccu_nm_round_rate(struct clk
+ _nm.max_m = nm->m.max ?: 1 << nm->m.width;
+
+ ccu_nm_find_best(*parent_rate, rate, &_nm);
+- rate = *parent_rate * _nm.n / _nm.m;
++ rate = ccu_nm_calc_rate(*parent_rate, _nm.n, _nm.m);
+
+ if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
+ rate /= nm->fixed_post_div;
--- /dev/null
+From bf287607c80f24387fedb431a346dc67f25be12c Mon Sep 17 00:00:00 2001
+From: Alexey Brodkin <alexey.brodkin@synopsys.com>
+Date: Mon, 19 Nov 2018 14:29:17 +0300
+Subject: clocksource/drivers/arc_timer: Utilize generic sched_clock
+
+From: Alexey Brodkin <alexey.brodkin@synopsys.com>
+
+commit bf287607c80f24387fedb431a346dc67f25be12c upstream.
+
+It turned out we used to use default implementation of sched_clock()
+from kernel/sched/clock.c which was as precise as 1/HZ, i.e.
+by default we had 10 msec granularity of time measurement.
+
+Now given ARC built-in timers are clocked with the same frequency as
+CPU cores we may get much higher precision of time tracking.
+
+Thus we switch to generic sched_clock which really reads ARC hardware
+counters.
+
+This is especially helpful for measuring short events.
+That's what we used to have:
+------------------------------>8------------------------
+$ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null
+
+ Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello':
+
+ 10.000000 task-clock (msec) # 2.832 CPUs utilized
+ 1 context-switches # 0.100 K/sec
+ 1 cpu-migrations # 0.100 K/sec
+ 63 page-faults # 0.006 M/sec
+ 3049480 cycles # 0.305 GHz
+ 1091259 instructions # 0.36 insn per cycle
+ 256828 branches # 25.683 M/sec
+ 27026 branch-misses # 10.52% of all branches
+
+ 0.003530687 seconds time elapsed
+
+ 0.000000000 seconds user
+ 0.010000000 seconds sys
+------------------------------>8------------------------
+
+And now we'll see:
+------------------------------>8------------------------
+$ perf stat /bin/sh -c /root/lmbench-master/bin/arc/hello > /dev/null
+
+ Performance counter stats for '/bin/sh -c /root/lmbench-master/bin/arc/hello':
+
+ 3.004322 task-clock (msec) # 0.865 CPUs utilized
+ 1 context-switches # 0.333 K/sec
+ 1 cpu-migrations # 0.333 K/sec
+ 63 page-faults # 0.021 M/sec
+ 2986734 cycles # 0.994 GHz
+ 1087466 instructions # 0.36 insn per cycle
+ 255209 branches # 84.947 M/sec
+ 26002 branch-misses # 10.19% of all branches
+
+ 0.003474829 seconds time elapsed
+
+ 0.003519000 seconds user
+ 0.000000000 seconds sys
+------------------------------>8------------------------
+
+Note how much more meaningful is the second output - time spent for
+execution pretty much matches number of cycles spent (we're runnign
+@ 1GHz here).
+
+Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Vineet Gupta <vgupta@synopsys.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Acked-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/Kconfig | 1 +
+ drivers/clocksource/Kconfig | 1 +
+ drivers/clocksource/arc_timer.c | 22 ++++++++++++++++++++++
+ 3 files changed, 24 insertions(+)
+
+--- a/arch/arc/Kconfig
++++ b/arch/arc/Kconfig
+@@ -26,6 +26,7 @@ config ARC
+ select GENERIC_IRQ_SHOW
+ select GENERIC_PCI_IOMAP
+ select GENERIC_PENDING_IRQ if SMP
++ select GENERIC_SCHED_CLOCK
+ select GENERIC_SMP_IDLE_THREAD
+ select HAVE_ARCH_KGDB
+ select HAVE_ARCH_TRACEHOOK
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -290,6 +290,7 @@ config CLKSRC_MPS2
+
+ config ARC_TIMERS
+ bool "Support for 32-bit TIMERn counters in ARC Cores" if COMPILE_TEST
++ depends on GENERIC_SCHED_CLOCK
+ select TIMER_OF
+ help
+ These are legacy 32-bit TIMER0 and TIMER1 counters found on all ARC cores
+--- a/drivers/clocksource/arc_timer.c
++++ b/drivers/clocksource/arc_timer.c
+@@ -23,6 +23,7 @@
+ #include <linux/cpu.h>
+ #include <linux/of.h>
+ #include <linux/of_irq.h>
++#include <linux/sched_clock.h>
+
+ #include <soc/arc/timers.h>
+ #include <soc/arc/mcip.h>
+@@ -88,6 +89,11 @@ static u64 arc_read_gfrc(struct clocksou
+ return (((u64)h) << 32) | l;
+ }
+
++static notrace u64 arc_gfrc_clock_read(void)
++{
++ return arc_read_gfrc(NULL);
++}
++
+ static struct clocksource arc_counter_gfrc = {
+ .name = "ARConnect GFRC",
+ .rating = 400,
+@@ -111,6 +117,8 @@ static int __init arc_cs_setup_gfrc(stru
+ if (ret)
+ return ret;
+
++ sched_clock_register(arc_gfrc_clock_read, 64, arc_timer_freq);
++
+ return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
+ }
+ TIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
+@@ -139,6 +147,11 @@ static u64 arc_read_rtc(struct clocksour
+ return (((u64)h) << 32) | l;
+ }
+
++static notrace u64 arc_rtc_clock_read(void)
++{
++ return arc_read_rtc(NULL);
++}
++
+ static struct clocksource arc_counter_rtc = {
+ .name = "ARCv2 RTC",
+ .rating = 350,
+@@ -170,6 +183,8 @@ static int __init arc_cs_setup_rtc(struc
+
+ write_aux_reg(AUX_RTC_CTRL, 1);
+
++ sched_clock_register(arc_rtc_clock_read, 64, arc_timer_freq);
++
+ return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
+ }
+ TIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
+@@ -185,6 +200,11 @@ static u64 arc_read_timer1(struct clocks
+ return (u64) read_aux_reg(ARC_REG_TIMER1_CNT);
+ }
+
++static notrace u64 arc_timer1_clock_read(void)
++{
++ return arc_read_timer1(NULL);
++}
++
+ static struct clocksource arc_counter_timer1 = {
+ .name = "ARC Timer1",
+ .rating = 300,
+@@ -209,6 +229,8 @@ static int __init arc_cs_setup_timer1(st
+ write_aux_reg(ARC_REG_TIMER1_CNT, 0);
+ write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
+
++ sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq);
++
+ return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
+ }
+
--- /dev/null
+From 7172122be6a4712d699da4d261f92aa5ab3a78b8 Mon Sep 17 00:00:00 2001
+From: Wenwen Wang <wang6495@umn.edu>
+Date: Thu, 18 Oct 2018 19:50:43 -0500
+Subject: crypto: cavium/nitrox - fix a DMA pool free failure
+
+From: Wenwen Wang <wang6495@umn.edu>
+
+commit 7172122be6a4712d699da4d261f92aa5ab3a78b8 upstream.
+
+In crypto_alloc_context(), a DMA pool is allocated through dma_pool_alloc()
+to hold the crypto context. The meta data of the DMA pool, including the
+pool used for the allocation 'ndev->ctx_pool' and the base address of the
+DMA pool used by the device 'dma', are then stored to the beginning of the
+pool. These meta data are eventually used in crypto_free_context() to free
+the DMA pool through dma_pool_free(). However, given that the DMA pool can
+also be accessed by the device, a malicious device can modify these meta
+data, especially when the device is controlled to deploy an attack. This
+can cause an unexpected DMA pool free failure.
+
+To avoid the above issue, this patch introduces a new structure
+crypto_ctx_hdr and a new field chdr in the structure nitrox_crypto_ctx hold
+the meta data information of the DMA pool after the allocation. Note that
+the original structure ctx_hdr is not changed to ensure the compatibility.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Wenwen Wang <wang6495@umn.edu>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/cavium/nitrox/nitrox_algs.c | 12 +++++++-----
+ drivers/crypto/cavium/nitrox/nitrox_lib.c | 22 +++++++++++++++++-----
+ drivers/crypto/cavium/nitrox/nitrox_req.h | 7 +++++++
+ 3 files changed, 31 insertions(+), 10 deletions(-)
+
+--- a/drivers/crypto/cavium/nitrox/nitrox_algs.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_algs.c
+@@ -73,7 +73,7 @@ static int flexi_aes_keylen(int keylen)
+ static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
+ {
+ struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
+- void *fctx;
++ struct crypto_ctx_hdr *chdr;
+
+ /* get the first device */
+ nctx->ndev = nitrox_get_first_device();
+@@ -81,12 +81,14 @@ static int nitrox_skcipher_init(struct c
+ return -ENODEV;
+
+ /* allocate nitrox crypto context */
+- fctx = crypto_alloc_context(nctx->ndev);
+- if (!fctx) {
++ chdr = crypto_alloc_context(nctx->ndev);
++ if (!chdr) {
+ nitrox_put_device(nctx->ndev);
+ return -ENOMEM;
+ }
+- nctx->u.ctx_handle = (uintptr_t)fctx;
++ nctx->chdr = chdr;
++ nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr +
++ sizeof(struct ctx_hdr));
+ crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(tfm) +
+ sizeof(struct nitrox_kcrypt_request));
+ return 0;
+@@ -102,7 +104,7 @@ static void nitrox_skcipher_exit(struct
+
+ memset(&fctx->crypto, 0, sizeof(struct crypto_keys));
+ memset(&fctx->auth, 0, sizeof(struct auth_keys));
+- crypto_free_context((void *)fctx);
++ crypto_free_context((void *)nctx->chdr);
+ }
+ nitrox_put_device(nctx->ndev);
+
+--- a/drivers/crypto/cavium/nitrox/nitrox_lib.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_lib.c
+@@ -146,12 +146,19 @@ static void destroy_crypto_dma_pool(stru
+ void *crypto_alloc_context(struct nitrox_device *ndev)
+ {
+ struct ctx_hdr *ctx;
++ struct crypto_ctx_hdr *chdr;
+ void *vaddr;
+ dma_addr_t dma;
+
++ chdr = kmalloc(sizeof(*chdr), GFP_KERNEL);
++ if (!chdr)
++ return NULL;
++
+ vaddr = dma_pool_alloc(ndev->ctx_pool, (GFP_KERNEL | __GFP_ZERO), &dma);
+- if (!vaddr)
++ if (!vaddr) {
++ kfree(chdr);
+ return NULL;
++ }
+
+ /* fill meta data */
+ ctx = vaddr;
+@@ -159,7 +166,11 @@ void *crypto_alloc_context(struct nitrox
+ ctx->dma = dma;
+ ctx->ctx_dma = dma + sizeof(struct ctx_hdr);
+
+- return ((u8 *)vaddr + sizeof(struct ctx_hdr));
++ chdr->pool = ndev->ctx_pool;
++ chdr->dma = dma;
++ chdr->vaddr = vaddr;
++
++ return chdr;
+ }
+
+ /**
+@@ -168,13 +179,14 @@ void *crypto_alloc_context(struct nitrox
+ */
+ void crypto_free_context(void *ctx)
+ {
+- struct ctx_hdr *ctxp;
++ struct crypto_ctx_hdr *ctxp;
+
+ if (!ctx)
+ return;
+
+- ctxp = (struct ctx_hdr *)((u8 *)ctx - sizeof(struct ctx_hdr));
+- dma_pool_free(ctxp->pool, ctxp, ctxp->dma);
++ ctxp = ctx;
++ dma_pool_free(ctxp->pool, ctxp->vaddr, ctxp->dma);
++ kfree(ctxp);
+ }
+
+ /**
+--- a/drivers/crypto/cavium/nitrox/nitrox_req.h
++++ b/drivers/crypto/cavium/nitrox/nitrox_req.h
+@@ -181,12 +181,19 @@ struct flexi_crypto_context {
+ struct auth_keys auth;
+ };
+
++struct crypto_ctx_hdr {
++ struct dma_pool *pool;
++ dma_addr_t dma;
++ void *vaddr;
++};
++
+ struct nitrox_crypto_ctx {
+ struct nitrox_device *ndev;
+ union {
+ u64 ctx_handle;
+ struct flexi_crypto_context *fctx;
+ } u;
++ struct crypto_ctx_hdr *chdr;
+ };
+
+ struct nitrox_kcrypt_request {
--- /dev/null
+From fa4600734b74f74d9169c3015946d4722f8bcf79 Mon Sep 17 00:00:00 2001
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Date: Sat, 20 Oct 2018 02:01:52 +0300
+Subject: crypto: cfb - fix decryption
+
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+commit fa4600734b74f74d9169c3015946d4722f8bcf79 upstream.
+
+crypto_cfb_decrypt_segment() incorrectly XOR'ed generated keystream with
+IV, rather than with data stream, resulting in incorrect decryption.
+Test vectors will be added in the next patch.
+
+Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/cfb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/crypto/cfb.c
++++ b/crypto/cfb.c
+@@ -144,7 +144,7 @@ static int crypto_cfb_decrypt_segment(st
+
+ do {
+ crypto_cfb_encrypt_one(tfm, iv, dst);
+- crypto_xor(dst, iv, bsize);
++ crypto_xor(dst, src, bsize);
+ iv = src;
+
+ src += bsize;
--- /dev/null
+From c35828ea906a7c76632a0211e59c392903cd4615 Mon Sep 17 00:00:00 2001
+From: Atul Gupta <atul.gupta@chelsio.com>
+Date: Fri, 30 Nov 2018 14:31:48 +0530
+Subject: crypto: chcr - small packet Tx stalls the queue
+
+From: Atul Gupta <atul.gupta@chelsio.com>
+
+commit c35828ea906a7c76632a0211e59c392903cd4615 upstream.
+
+Immediate packets sent to hardware should include the work
+request length in calculating the flits. WR occupy one flit and
+if not accounted result in invalid request which stalls the HW
+queue.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Atul Gupta <atul.gupta@chelsio.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/chelsio/chcr_ipsec.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/crypto/chelsio/chcr_ipsec.c
++++ b/drivers/crypto/chelsio/chcr_ipsec.c
+@@ -303,7 +303,10 @@ static bool chcr_ipsec_offload_ok(struct
+
+ static inline int is_eth_imm(const struct sk_buff *skb, unsigned int kctx_len)
+ {
+- int hdrlen = sizeof(struct chcr_ipsec_req) + kctx_len;
++ int hdrlen;
++
++ hdrlen = sizeof(struct fw_ulptx_wr) +
++ sizeof(struct chcr_ipsec_req) + kctx_len;
+
+ hdrlen += sizeof(struct cpl_tx_pkt);
+ if (skb->len <= MAX_IMM_TX_PKT_LEN - hdrlen)
--- /dev/null
+From 7da66670775d201f633577f5b15a4bbeebaaa2b0 Mon Sep 17 00:00:00 2001
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Date: Sat, 20 Oct 2018 02:01:53 +0300
+Subject: crypto: testmgr - add AES-CFB tests
+
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+commit 7da66670775d201f633577f5b15a4bbeebaaa2b0 upstream.
+
+Add AES128/192/256-CFB testvectors from NIST SP800-38A.
+
+Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/tcrypt.c | 5 +++
+ crypto/testmgr.c | 7 +++++
+ crypto/testmgr.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 88 insertions(+)
+
+--- a/crypto/tcrypt.c
++++ b/crypto/tcrypt.c
+@@ -1736,6 +1736,7 @@ static int do_test(const char *alg, u32
+ ret += tcrypt_test("xts(aes)");
+ ret += tcrypt_test("ctr(aes)");
+ ret += tcrypt_test("rfc3686(ctr(aes))");
++ ret += tcrypt_test("cfb(aes)");
+ break;
+
+ case 11:
+@@ -2062,6 +2063,10 @@ static int do_test(const char *alg, u32
+ speed_template_16_24_32);
+ test_cipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
++ test_cipher_speed("cfb(aes)", ENCRYPT, sec, NULL, 0,
++ speed_template_16_24_32);
++ test_cipher_speed("cfb(aes)", DECRYPT, sec, NULL, 0,
++ speed_template_16_24_32);
+ break;
+
+ case 201:
+--- a/crypto/testmgr.c
++++ b/crypto/testmgr.c
+@@ -2685,6 +2685,13 @@ static const struct alg_test_desc alg_te
+ }
+ }
+ }, {
++ .alg = "cfb(aes)",
++ .test = alg_test_skcipher,
++ .fips_allowed = 1,
++ .suite = {
++ .cipher = __VECS(aes_cfb_tv_template)
++ },
++ }, {
+ .alg = "chacha20",
+ .test = alg_test_skcipher,
+ .suite = {
+--- a/crypto/testmgr.h
++++ b/crypto/testmgr.h
+@@ -11343,6 +11343,82 @@ static const struct cipher_testvec aes_c
+ },
+ };
+
++static const struct cipher_testvec aes_cfb_tv_template[] = {
++ { /* From NIST SP800-38A */
++ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
++ "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
++ .klen = 16,
++ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
++ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
++ .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
++ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
++ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
++ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
++ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
++ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
++ .ctext = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20"
++ "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a"
++ "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f"
++ "\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"
++ "\x26\x75\x1f\x67\xa3\xcb\xb1\x40"
++ "\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf"
++ "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e"
++ "\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6",
++ .len = 64,
++ }, {
++ .key = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
++ "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
++ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
++ .klen = 24,
++ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
++ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
++ .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
++ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
++ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
++ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
++ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
++ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
++ .ctext = "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab"
++ "\x34\xc2\x59\x09\xc9\x9a\x41\x74"
++ "\x67\xce\x7f\x7f\x81\x17\x36\x21"
++ "\x96\x1a\x2b\x70\x17\x1d\x3d\x7a"
++ "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1"
++ "\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9"
++ "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0"
++ "\x42\xae\x8f\xba\x58\x4b\x09\xff",
++ .len = 64,
++ }, {
++ .key = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
++ "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
++ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
++ "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
++ .klen = 32,
++ .iv = "\x00\x01\x02\x03\x04\x05\x06\x07"
++ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
++ .ptext = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
++ "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
++ "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
++ "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
++ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
++ "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
++ .ctext = "\xdc\x7e\x84\xbf\xda\x79\x16\x4b"
++ "\x7e\xcd\x84\x86\x98\x5d\x38\x60"
++ "\x39\xff\xed\x14\x3b\x28\xb1\xc8"
++ "\x32\x11\x3c\x63\x31\xe5\x40\x7b"
++ "\xdf\x10\x13\x24\x15\xe5\x4b\x92"
++ "\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9"
++ "\x75\xa3\x85\x74\x1a\xb9\xce\xf8"
++ "\x20\x31\x62\x3d\x55\xb1\xe4\x71",
++ .len = 64,
++ },
++};
++
+ static const struct aead_testvec hmac_md5_ecb_cipher_null_enc_tv_template[] = {
+ { /* Input data from RFC 2410 Case 1 */
+ #ifdef __LITTLE_ENDIAN
--- /dev/null
+From 32e932e37e6b6e13b66add307192c7ddd40a781d Mon Sep 17 00:00:00 2001
+From: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+Date: Fri, 28 Sep 2018 17:41:26 +0300
+Subject: DRM: UDL: get rid of useless vblank initialization
+
+From: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+
+commit 32e932e37e6b6e13b66add307192c7ddd40a781d upstream.
+
+UDL doesn't support vblank functionality so we don't need to
+initialize vblank here (we are able to send page flip
+completion events even without vblank initialization)
+
+Moreover current drm_vblank_init call with num_crtcs > 0 causes
+sending DRM_EVENT_FLIP_COMPLETE event with zero timestamp every
+time. This breaks userspace apps (for example weston) which
+relies on timestamp value.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20180928144126.21598-1-Eugeniy.Paltsev@synopsys.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_main.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/udl/udl_main.c
++++ b/drivers/gpu/drm/udl/udl_main.c
+@@ -350,15 +350,10 @@ int udl_driver_load(struct drm_device *d
+ if (ret)
+ goto err;
+
+- ret = drm_vblank_init(dev, 1);
+- if (ret)
+- goto err_fb;
+-
+ drm_kms_helper_poll_init(dev);
+
+ return 0;
+-err_fb:
+- udl_fbdev_cleanup(dev);
++
+ err:
+ if (udl->urbs.count)
+ udl_free_urb_list(dev);
--- /dev/null
+From 2f20fa8d12e859a03f68bdd81d75830141bc9ac9 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Fri, 28 Sep 2018 16:21:26 -0700
+Subject: drm/v3d: Skip debugfs dumping GCA on platforms without GCA.
+
+From: Eric Anholt <eric@anholt.net>
+
+commit 2f20fa8d12e859a03f68bdd81d75830141bc9ac9 upstream.
+
+Fixes an oops reading this debugfs entry on BCM7278.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+Link: https://patchwork.freedesktop.org/patch/msgid/20180928232126.4332-4-eric@anholt.net
+Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/v3d/v3d_debugfs.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
++++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
+@@ -71,10 +71,13 @@ static int v3d_v3d_debugfs_regs(struct s
+ V3D_READ(v3d_hub_reg_defs[i].reg));
+ }
+
+- for (i = 0; i < ARRAY_SIZE(v3d_gca_reg_defs); i++) {
+- seq_printf(m, "%s (0x%04x): 0x%08x\n",
+- v3d_gca_reg_defs[i].name, v3d_gca_reg_defs[i].reg,
+- V3D_GCA_READ(v3d_gca_reg_defs[i].reg));
++ if (v3d->ver < 41) {
++ for (i = 0; i < ARRAY_SIZE(v3d_gca_reg_defs); i++) {
++ seq_printf(m, "%s (0x%04x): 0x%08x\n",
++ v3d_gca_reg_defs[i].name,
++ v3d_gca_reg_defs[i].reg,
++ V3D_GCA_READ(v3d_gca_reg_defs[i].reg));
++ }
+ }
+
+ for (core = 0; core < v3d->cores; core++) {
--- /dev/null
+From fb265c9cb49e2074ddcdd4de99728aefdd3b3592 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 25 Nov 2018 17:20:31 -0500
+Subject: ext4: add ext4_sb_bread() to disambiguate ENOMEM cases
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit fb265c9cb49e2074ddcdd4de99728aefdd3b3592 upstream.
+
+Today, when sb_bread() returns NULL, this can either be because of an
+I/O error or because the system failed to allocate the buffer. Since
+it's an old interface, changing would require changing many call
+sites.
+
+So instead we create our own ext4_sb_bread(), which also allows us to
+set the REQ_META flag.
+
+Also fixed a problem in the xattr code where a NULL return in a
+function could also mean that the xattr was not found, which could
+lead to the wrong error getting returned to userspace.
+
+Fixes: ac27a0ec112a ("ext4: initial copy of files from ext3")
+Cc: stable@kernel.org # 2.6.19
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4.h | 2 +
+ fs/ext4/migrate.c | 36 ++++++++++++-------------
+ fs/ext4/resize.c | 72 +++++++++++++++++++++++++--------------------------
+ fs/ext4/super.c | 23 ++++++++++++++++
+ fs/ext4/xattr.c | 76 +++++++++++++++++++++++++-----------------------------
+ 5 files changed, 115 insertions(+), 94 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2542,6 +2542,8 @@ extern int ext4_group_extend(struct supe
+ extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
+
+ /* super.c */
++extern struct buffer_head *ext4_sb_bread(struct super_block *sb,
++ sector_t block, int op_flags);
+ extern int ext4_seq_options_show(struct seq_file *seq, void *offset);
+ extern int ext4_calculate_overhead(struct super_block *sb);
+ extern void ext4_superblock_csum_set(struct super_block *sb);
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -116,9 +116,9 @@ static int update_ind_extent_range(handl
+ int i, retval = 0;
+ unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+
+- bh = sb_bread(inode->i_sb, pblock);
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, pblock, 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ i_data = (__le32 *)bh->b_data;
+ for (i = 0; i < max_entries; i++) {
+@@ -145,9 +145,9 @@ static int update_dind_extent_range(hand
+ int i, retval = 0;
+ unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+
+- bh = sb_bread(inode->i_sb, pblock);
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, pblock, 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ i_data = (__le32 *)bh->b_data;
+ for (i = 0; i < max_entries; i++) {
+@@ -175,9 +175,9 @@ static int update_tind_extent_range(hand
+ int i, retval = 0;
+ unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+
+- bh = sb_bread(inode->i_sb, pblock);
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, pblock, 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ i_data = (__le32 *)bh->b_data;
+ for (i = 0; i < max_entries; i++) {
+@@ -224,9 +224,9 @@ static int free_dind_blocks(handle_t *ha
+ struct buffer_head *bh;
+ unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+
+- bh = sb_bread(inode->i_sb, le32_to_cpu(i_data));
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ tmp_idata = (__le32 *)bh->b_data;
+ for (i = 0; i < max_entries; i++) {
+@@ -254,9 +254,9 @@ static int free_tind_blocks(handle_t *ha
+ struct buffer_head *bh;
+ unsigned long max_entries = inode->i_sb->s_blocksize >> 2;
+
+- bh = sb_bread(inode->i_sb, le32_to_cpu(i_data));
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, le32_to_cpu(i_data), 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ tmp_idata = (__le32 *)bh->b_data;
+ for (i = 0; i < max_entries; i++) {
+@@ -382,9 +382,9 @@ static int free_ext_idx(handle_t *handle
+ struct ext4_extent_header *eh;
+
+ block = ext4_idx_pblock(ix);
+- bh = sb_bread(inode->i_sb, block);
+- if (!bh)
+- return -EIO;
++ bh = ext4_sb_bread(inode->i_sb, block, 0);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+
+ eh = (struct ext4_extent_header *)bh->b_data;
+ if (eh->eh_depth != 0) {
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -127,10 +127,12 @@ static int verify_group_input(struct sup
+ else if (free_blocks_count < 0)
+ ext4_warning(sb, "Bad blocks count %u",
+ input->blocks_count);
+- else if (!(bh = sb_bread(sb, end - 1)))
++ else if (IS_ERR(bh = ext4_sb_bread(sb, end - 1, 0))) {
++ err = PTR_ERR(bh);
++ bh = NULL;
+ ext4_warning(sb, "Cannot read last block (%llu)",
+ end - 1);
+- else if (outside(input->block_bitmap, start, end))
++ } else if (outside(input->block_bitmap, start, end))
+ ext4_warning(sb, "Block bitmap not in group (block %llu)",
+ (unsigned long long)input->block_bitmap);
+ else if (outside(input->inode_bitmap, start, end))
+@@ -781,11 +783,11 @@ static int add_new_gdb(handle_t *handle,
+ struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+ unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+ ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num;
+- struct buffer_head **o_group_desc, **n_group_desc;
+- struct buffer_head *dind;
+- struct buffer_head *gdb_bh;
++ struct buffer_head **o_group_desc, **n_group_desc = NULL;
++ struct buffer_head *dind = NULL;
++ struct buffer_head *gdb_bh = NULL;
+ int gdbackups;
+- struct ext4_iloc iloc;
++ struct ext4_iloc iloc = { .bh = NULL };
+ __le32 *data;
+ int err;
+
+@@ -794,21 +796,22 @@ static int add_new_gdb(handle_t *handle,
+ "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n",
+ gdb_num);
+
+- gdb_bh = sb_bread(sb, gdblock);
+- if (!gdb_bh)
+- return -EIO;
++ gdb_bh = ext4_sb_bread(sb, gdblock, 0);
++ if (IS_ERR(gdb_bh))
++ return PTR_ERR(gdb_bh);
+
+ gdbackups = verify_reserved_gdb(sb, group, gdb_bh);
+ if (gdbackups < 0) {
+ err = gdbackups;
+- goto exit_bh;
++ goto errout;
+ }
+
+ data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
+- dind = sb_bread(sb, le32_to_cpu(*data));
+- if (!dind) {
+- err = -EIO;
+- goto exit_bh;
++ dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0);
++ if (IS_ERR(dind)) {
++ err = PTR_ERR(dind);
++ dind = NULL;
++ goto errout;
+ }
+
+ data = (__le32 *)dind->b_data;
+@@ -816,18 +819,18 @@ static int add_new_gdb(handle_t *handle,
+ ext4_warning(sb, "new group %u GDT block %llu not reserved",
+ group, gdblock);
+ err = -EINVAL;
+- goto exit_dind;
++ goto errout;
+ }
+
+ BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+ if (unlikely(err))
+- goto exit_dind;
++ goto errout;
+
+ BUFFER_TRACE(gdb_bh, "get_write_access");
+ err = ext4_journal_get_write_access(handle, gdb_bh);
+ if (unlikely(err))
+- goto exit_dind;
++ goto errout;
+
+ BUFFER_TRACE(dind, "get_write_access");
+ err = ext4_journal_get_write_access(handle, dind);
+@@ -837,7 +840,7 @@ static int add_new_gdb(handle_t *handle,
+ /* ext4_reserve_inode_write() gets a reference on the iloc */
+ err = ext4_reserve_inode_write(handle, inode, &iloc);
+ if (unlikely(err))
+- goto exit_dind;
++ goto errout;
+
+ n_group_desc = ext4_kvmalloc((gdb_num + 1) *
+ sizeof(struct buffer_head *),
+@@ -846,7 +849,7 @@ static int add_new_gdb(handle_t *handle,
+ err = -ENOMEM;
+ ext4_warning(sb, "not enough memory for %lu groups",
+ gdb_num + 1);
+- goto exit_inode;
++ goto errout;
+ }
+
+ /*
+@@ -862,7 +865,7 @@ static int add_new_gdb(handle_t *handle,
+ err = ext4_handle_dirty_metadata(handle, NULL, dind);
+ if (unlikely(err)) {
+ ext4_std_error(sb, err);
+- goto exit_inode;
++ goto errout;
+ }
+ inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >>
+ (9 - EXT4_SB(sb)->s_cluster_bits);
+@@ -871,8 +874,7 @@ static int add_new_gdb(handle_t *handle,
+ err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh);
+ if (unlikely(err)) {
+ ext4_std_error(sb, err);
+- iloc.bh = NULL;
+- goto exit_inode;
++ goto errout;
+ }
+ brelse(dind);
+
+@@ -888,15 +890,11 @@ static int add_new_gdb(handle_t *handle,
+ err = ext4_handle_dirty_super(handle, sb);
+ if (err)
+ ext4_std_error(sb, err);
+-
+ return err;
+-
+-exit_inode:
++errout:
+ kvfree(n_group_desc);
+ brelse(iloc.bh);
+-exit_dind:
+ brelse(dind);
+-exit_bh:
+ brelse(gdb_bh);
+
+ ext4_debug("leaving with error %d\n", err);
+@@ -916,9 +914,9 @@ static int add_new_gdb_meta_bg(struct su
+
+ gdblock = ext4_meta_bg_first_block_no(sb, group) +
+ ext4_bg_has_super(sb, group);
+- gdb_bh = sb_bread(sb, gdblock);
+- if (!gdb_bh)
+- return -EIO;
++ gdb_bh = ext4_sb_bread(sb, gdblock, 0);
++ if (IS_ERR(gdb_bh))
++ return PTR_ERR(gdb_bh);
+ n_group_desc = ext4_kvmalloc((gdb_num + 1) *
+ sizeof(struct buffer_head *),
+ GFP_NOFS);
+@@ -975,9 +973,10 @@ static int reserve_backup_gdb(handle_t *
+ return -ENOMEM;
+
+ data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK;
+- dind = sb_bread(sb, le32_to_cpu(*data));
+- if (!dind) {
+- err = -EIO;
++ dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0);
++ if (IS_ERR(dind)) {
++ err = PTR_ERR(dind);
++ dind = NULL;
+ goto exit_free;
+ }
+
+@@ -996,9 +995,10 @@ static int reserve_backup_gdb(handle_t *
+ err = -EINVAL;
+ goto exit_bh;
+ }
+- primary[res] = sb_bread(sb, blk);
+- if (!primary[res]) {
+- err = -EIO;
++ primary[res] = ext4_sb_bread(sb, blk, 0);
++ if (IS_ERR(primary[res])) {
++ err = PTR_ERR(primary[res]);
++ primary[res] = NULL;
+ goto exit_bh;
+ }
+ gdbackups = verify_reserved_gdb(sb, group, primary[res]);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -140,6 +140,29 @@ MODULE_ALIAS_FS("ext3");
+ MODULE_ALIAS("ext3");
+ #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
+
++/*
++ * This works like sb_bread() except it uses ERR_PTR for error
++ * returns. Currently with sb_bread it's impossible to distinguish
++ * between ENOMEM and EIO situations (since both result in a NULL
++ * return.
++ */
++struct buffer_head *
++ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags)
++{
++ struct buffer_head *bh = sb_getblk(sb, block);
++
++ if (bh == NULL)
++ return ERR_PTR(-ENOMEM);
++ if (buffer_uptodate(bh))
++ return bh;
++ ll_rw_block(REQ_OP_READ, REQ_META | op_flags, 1, &bh);
++ wait_on_buffer(bh);
++ if (buffer_uptodate(bh))
++ return bh;
++ put_bh(bh);
++ return ERR_PTR(-EIO);
++}
++
+ static int ext4_verify_csum_type(struct super_block *sb,
+ struct ext4_super_block *es)
+ {
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -522,14 +522,13 @@ ext4_xattr_block_get(struct inode *inode
+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
+ name_index, name, buffer, (long)buffer_size);
+
+- error = -ENODATA;
+ if (!EXT4_I(inode)->i_file_acl)
+- goto cleanup;
++ return -ENODATA;
+ ea_idebug(inode, "reading block %llu",
+ (unsigned long long)EXT4_I(inode)->i_file_acl);
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- if (!bh)
+- goto cleanup;
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+ ea_bdebug(bh, "b_count=%d, refcount=%d",
+ atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+ error = ext4_xattr_check_block(inode, bh);
+@@ -696,26 +695,23 @@ ext4_xattr_block_list(struct dentry *den
+ ea_idebug(inode, "buffer=%p, buffer_size=%ld",
+ buffer, (long)buffer_size);
+
+- error = 0;
+ if (!EXT4_I(inode)->i_file_acl)
+- goto cleanup;
++ return 0;
+ ea_idebug(inode, "reading block %llu",
+ (unsigned long long)EXT4_I(inode)->i_file_acl);
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- error = -EIO;
+- if (!bh)
+- goto cleanup;
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh))
++ return PTR_ERR(bh);
+ ea_bdebug(bh, "b_count=%d, refcount=%d",
+ atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+ error = ext4_xattr_check_block(inode, bh);
+ if (error)
+ goto cleanup;
+ ext4_xattr_block_cache_insert(EA_BLOCK_CACHE(inode), bh);
+- error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);
+-
++ error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer,
++ buffer_size);
+ cleanup:
+ brelse(bh);
+-
+ return error;
+ }
+
+@@ -830,9 +826,9 @@ int ext4_get_inode_usage(struct inode *i
+ }
+
+ if (EXT4_I(inode)->i_file_acl) {
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- if (!bh) {
+- ret = -EIO;
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh)) {
++ ret = PTR_ERR(bh);
+ goto out;
+ }
+
+@@ -1825,16 +1821,15 @@ ext4_xattr_block_find(struct inode *inod
+
+ if (EXT4_I(inode)->i_file_acl) {
+ /* The inode already has an extended attribute block. */
+- bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl);
+- error = -EIO;
+- if (!bs->bh)
+- goto cleanup;
++ bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bs->bh))
++ return PTR_ERR(bs->bh);
+ ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
+ atomic_read(&(bs->bh->b_count)),
+ le32_to_cpu(BHDR(bs->bh)->h_refcount));
+ error = ext4_xattr_check_block(inode, bs->bh);
+ if (error)
+- goto cleanup;
++ return error;
+ /* Find the named attribute. */
+ bs->s.base = BHDR(bs->bh);
+ bs->s.first = BFIRST(bs->bh);
+@@ -1843,13 +1838,10 @@ ext4_xattr_block_find(struct inode *inod
+ error = xattr_find_entry(inode, &bs->s.here, bs->s.end,
+ i->name_index, i->name, 1);
+ if (error && error != -ENODATA)
+- goto cleanup;
++ return error;
+ bs->s.not_found = error;
+ }
+- error = 0;
+-
+-cleanup:
+- return error;
++ return 0;
+ }
+
+ static int
+@@ -2278,9 +2270,9 @@ static struct buffer_head *ext4_xattr_ge
+
+ if (!EXT4_I(inode)->i_file_acl)
+ return NULL;
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- if (!bh)
+- return ERR_PTR(-EIO);
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh))
++ return bh;
+ error = ext4_xattr_check_block(inode, bh);
+ if (error) {
+ brelse(bh);
+@@ -2750,10 +2742,11 @@ retry:
+ if (EXT4_I(inode)->i_file_acl) {
+ struct buffer_head *bh;
+
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- error = -EIO;
+- if (!bh)
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh)) {
++ error = PTR_ERR(bh);
+ goto cleanup;
++ }
+ error = ext4_xattr_check_block(inode, bh);
+ if (error) {
+ brelse(bh);
+@@ -2907,11 +2900,12 @@ int ext4_xattr_delete_inode(handle_t *ha
+ }
+
+ if (EXT4_I(inode)->i_file_acl) {
+- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+- if (!bh) {
+- EXT4_ERROR_INODE(inode, "block %llu read error",
+- EXT4_I(inode)->i_file_acl);
+- error = -EIO;
++ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl, REQ_PRIO);
++ if (IS_ERR(bh)) {
++ error = PTR_ERR(bh);
++ if (error == -EIO)
++ EXT4_ERROR_INODE(inode, "block %llu read error",
++ EXT4_I(inode)->i_file_acl);
+ goto cleanup;
+ }
+ error = ext4_xattr_check_block(inode, bh);
+@@ -3064,8 +3058,10 @@ ext4_xattr_block_cache_find(struct inode
+ while (ce) {
+ struct buffer_head *bh;
+
+- bh = sb_bread(inode->i_sb, ce->e_value);
+- if (!bh) {
++ bh = ext4_sb_bread(inode->i_sb, ce->e_value, REQ_PRIO);
++ if (IS_ERR(bh)) {
++ if (PTR_ERR(bh) == -ENOMEM)
++ return NULL;
+ EXT4_ERROR_INODE(inode, "block %lu read error",
+ (unsigned long)ce->e_value);
+ } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
--- /dev/null
+From 8a363970d1dc38c4ec4ad575c862f776f468d057 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 19 Dec 2018 12:29:13 -0500
+Subject: ext4: avoid declaring fs inconsistent due to invalid file handles
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 8a363970d1dc38c4ec4ad575c862f776f468d057 upstream.
+
+If we receive a file handle, either from NFS or open_by_handle_at(2),
+and it points at an inode which has not been initialized, and the file
+system has metadata checksums enabled, we shouldn't try to get the
+inode, discover the checksum is invalid, and then declare the file
+system as being inconsistent.
+
+This can be reproduced by creating a test file system via "mke2fs -t
+ext4 -O metadata_csum /tmp/foo.img 8M", mounting it, cd'ing into that
+directory, and then running the following program.
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+
+struct handle {
+ struct file_handle fh;
+ unsigned char fid[MAX_HANDLE_SZ];
+};
+
+int main(int argc, char **argv)
+{
+ struct handle h = {{8, 1 }, { 12, }};
+
+ open_by_handle_at(AT_FDCWD, &h.fh, O_RDONLY);
+ return 0;
+}
+
+Google-Bug-Id: 120690101
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4.h | 15 +++++++++++++--
+ fs/ext4/ialloc.c | 2 +-
+ fs/ext4/inode.c | 54 +++++++++++++++++++++++++++++++++++++-----------------
+ fs/ext4/ioctl.c | 2 +-
+ fs/ext4/namei.c | 4 ++--
+ fs/ext4/resize.c | 5 +++--
+ fs/ext4/super.c | 19 +++++--------------
+ fs/ext4/xattr.c | 5 +++--
+ 8 files changed, 65 insertions(+), 41 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2459,8 +2459,19 @@ int do_journal_get_write_access(handle_t
+ #define FALL_BACK_TO_NONDELALLOC 1
+ #define CONVERT_INLINE_DATA 2
+
+-extern struct inode *ext4_iget(struct super_block *, unsigned long);
+-extern struct inode *ext4_iget_normal(struct super_block *, unsigned long);
++typedef enum {
++ EXT4_IGET_NORMAL = 0,
++ EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */
++ EXT4_IGET_HANDLE = 0x0002 /* Inode # is from a handle */
++} ext4_iget_flags;
++
++extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
++ ext4_iget_flags flags, const char *function,
++ unsigned int line);
++
++#define ext4_iget(sb, ino, flags) \
++ __ext4_iget((sb), (ino), (flags), __func__, __LINE__)
++
+ extern int ext4_write_inode(struct inode *, struct writeback_control *);
+ extern int ext4_setattr(struct dentry *, struct iattr *);
+ extern int ext4_getattr(const struct path *, struct kstat *, u32, unsigned int);
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1225,7 +1225,7 @@ struct inode *ext4_orphan_get(struct sup
+ if (!ext4_test_bit(bit, bitmap_bh->b_data))
+ goto bad_orphan;
+
+- inode = ext4_iget(sb, ino);
++ inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4786,7 +4786,9 @@ static inline u64 ext4_inode_peek_iversi
+ return inode_peek_iversion(inode);
+ }
+
+-struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
++struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
++ ext4_iget_flags flags, const char *function,
++ unsigned int line)
+ {
+ struct ext4_iloc iloc;
+ struct ext4_inode *raw_inode;
+@@ -4800,6 +4802,18 @@ struct inode *ext4_iget(struct super_blo
+ gid_t i_gid;
+ projid_t i_projid;
+
++ if (((flags & EXT4_IGET_NORMAL) &&
++ (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)) ||
++ (ino < EXT4_ROOT_INO) ||
++ (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))) {
++ if (flags & EXT4_IGET_HANDLE)
++ return ERR_PTR(-ESTALE);
++ __ext4_error(sb, function, line,
++ "inode #%lu: comm %s: iget: illegal inode #",
++ ino, current->comm);
++ return ERR_PTR(-EFSCORRUPTED);
++ }
++
+ inode = iget_locked(sb, ino);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+@@ -4815,18 +4829,26 @@ struct inode *ext4_iget(struct super_blo
+ raw_inode = ext4_raw_inode(&iloc);
+
+ if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) {
+- EXT4_ERROR_INODE(inode, "root inode unallocated");
++ ext4_error_inode(inode, function, line, 0,
++ "iget: root inode unallocated");
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+ }
+
++ if ((flags & EXT4_IGET_HANDLE) &&
++ (raw_inode->i_links_count == 0) && (raw_inode->i_mode == 0)) {
++ ret = -ESTALE;
++ goto bad_inode;
++ }
++
+ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
+ ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
+ if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
+ EXT4_INODE_SIZE(inode->i_sb) ||
+ (ei->i_extra_isize & 3)) {
+- EXT4_ERROR_INODE(inode,
+- "bad extra_isize %u (inode size %u)",
++ ext4_error_inode(inode, function, line, 0,
++ "iget: bad extra_isize %u "
++ "(inode size %u)",
+ ei->i_extra_isize,
+ EXT4_INODE_SIZE(inode->i_sb));
+ ret = -EFSCORRUPTED;
+@@ -4848,7 +4870,8 @@ struct inode *ext4_iget(struct super_blo
+ }
+
+ if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
+- EXT4_ERROR_INODE(inode, "checksum invalid");
++ ext4_error_inode(inode, function, line, 0,
++ "iget: checksum invalid");
+ ret = -EFSBADCRC;
+ goto bad_inode;
+ }
+@@ -4905,7 +4928,8 @@ struct inode *ext4_iget(struct super_blo
+ ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
+ inode->i_size = ext4_isize(sb, raw_inode);
+ if ((size = i_size_read(inode)) < 0) {
+- EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size);
++ ext4_error_inode(inode, function, line, 0,
++ "iget: bad i_size value: %lld", size);
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+ }
+@@ -4981,7 +5005,8 @@ struct inode *ext4_iget(struct super_blo
+ ret = 0;
+ if (ei->i_file_acl &&
+ !ext4_data_block_valid(EXT4_SB(sb), ei->i_file_acl, 1)) {
+- EXT4_ERROR_INODE(inode, "bad extended attribute block %llu",
++ ext4_error_inode(inode, function, line, 0,
++ "iget: bad extended attribute block %llu",
+ ei->i_file_acl);
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+@@ -5009,8 +5034,9 @@ struct inode *ext4_iget(struct super_blo
+ } else if (S_ISLNK(inode->i_mode)) {
+ /* VFS does not allow setting these so must be corruption */
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+- EXT4_ERROR_INODE(inode,
+- "immutable or append flags not allowed on symlinks");
++ ext4_error_inode(inode, function, line, 0,
++ "iget: immutable or append flags "
++ "not allowed on symlinks");
+ ret = -EFSCORRUPTED;
+ goto bad_inode;
+ }
+@@ -5040,7 +5066,8 @@ struct inode *ext4_iget(struct super_blo
+ make_bad_inode(inode);
+ } else {
+ ret = -EFSCORRUPTED;
+- EXT4_ERROR_INODE(inode, "bogus i_mode (%o)", inode->i_mode);
++ ext4_error_inode(inode, function, line, 0,
++ "iget: bogus i_mode (%o)", inode->i_mode);
+ goto bad_inode;
+ }
+ brelse(iloc.bh);
+@@ -5054,13 +5081,6 @@ bad_inode:
+ return ERR_PTR(ret);
+ }
+
+-struct inode *ext4_iget_normal(struct super_block *sb, unsigned long ino)
+-{
+- if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
+- return ERR_PTR(-EFSCORRUPTED);
+- return ext4_iget(sb, ino);
+-}
+-
+ static int ext4_inode_blocks_set(handle_t *handle,
+ struct ext4_inode *raw_inode,
+ struct ext4_inode_info *ei)
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -125,7 +125,7 @@ static long swap_inode_boot_loader(struc
+ !inode_owner_or_capable(inode) || !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+- inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO);
++ inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
+ if (IS_ERR(inode_bl))
+ return PTR_ERR(inode_bl);
+ ei_bl = EXT4_I(inode_bl);
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1571,7 +1571,7 @@ static struct dentry *ext4_lookup(struct
+ dentry);
+ return ERR_PTR(-EFSCORRUPTED);
+ }
+- inode = ext4_iget_normal(dir->i_sb, ino);
++ inode = ext4_iget(dir->i_sb, ino, EXT4_IGET_NORMAL);
+ if (inode == ERR_PTR(-ESTALE)) {
+ EXT4_ERROR_INODE(dir,
+ "deleted inode referenced: %u",
+@@ -1613,7 +1613,7 @@ struct dentry *ext4_get_parent(struct de
+ return ERR_PTR(-EFSCORRUPTED);
+ }
+
+- return d_obtain_alias(ext4_iget_normal(child->d_sb, ino));
++ return d_obtain_alias(ext4_iget(child->d_sb, ino, EXT4_IGET_NORMAL));
+ }
+
+ /*
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1637,7 +1637,7 @@ int ext4_group_add(struct super_block *s
+ "No reserved GDT blocks, can't resize");
+ return -EPERM;
+ }
+- inode = ext4_iget(sb, EXT4_RESIZE_INO);
++ inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL);
+ if (IS_ERR(inode)) {
+ ext4_warning(sb, "Error opening resize inode");
+ return PTR_ERR(inode);
+@@ -1965,7 +1965,8 @@ retry:
+ }
+
+ if (!resize_inode)
+- resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
++ resize_inode = ext4_iget(sb, EXT4_RESIZE_INO,
++ EXT4_IGET_SPECIAL);
+ if (IS_ERR(resize_inode)) {
+ ext4_warning(sb, "Error opening resize inode");
+ return PTR_ERR(resize_inode);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1173,20 +1173,11 @@ static struct inode *ext4_nfs_get_inode(
+ {
+ struct inode *inode;
+
+- if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
+- return ERR_PTR(-ESTALE);
+- if (ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
+- return ERR_PTR(-ESTALE);
+-
+- /* iget isn't really right if the inode is currently unallocated!!
+- *
+- * ext4_read_inode will return a bad_inode if the inode had been
+- * deleted, so we should be safe.
+- *
++ /*
+ * Currently we don't know the generation for parent directory, so
+ * a generation of 0 means "accept any"
+ */
+- inode = ext4_iget_normal(sb, ino);
++ inode = ext4_iget(sb, ino, EXT4_IGET_HANDLE);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ if (generation && inode->i_generation != generation) {
+@@ -4350,7 +4341,7 @@ no_journal:
+ * so we can safely mount the rest of the filesystem now.
+ */
+
+- root = ext4_iget(sb, EXT4_ROOT_INO);
++ root = ext4_iget(sb, EXT4_ROOT_INO, EXT4_IGET_SPECIAL);
+ if (IS_ERR(root)) {
+ ext4_msg(sb, KERN_ERR, "get root inode failed");
+ ret = PTR_ERR(root);
+@@ -4620,7 +4611,7 @@ static struct inode *ext4_get_journal_in
+ * happen if we iget() an unused inode, as the subsequent iput()
+ * will try to delete it.
+ */
+- journal_inode = ext4_iget(sb, journal_inum);
++ journal_inode = ext4_iget(sb, journal_inum, EXT4_IGET_SPECIAL);
+ if (IS_ERR(journal_inode)) {
+ ext4_msg(sb, KERN_ERR, "no journal found");
+ return NULL;
+@@ -5702,7 +5693,7 @@ static int ext4_quota_enable(struct supe
+ if (!qf_inums[type])
+ return -EPERM;
+
+- qf_inode = ext4_iget(sb, qf_inums[type]);
++ qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
+ if (IS_ERR(qf_inode)) {
+ ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
+ return PTR_ERR(qf_inode);
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -384,7 +384,7 @@ static int ext4_xattr_inode_iget(struct
+ struct inode *inode;
+ int err;
+
+- inode = ext4_iget(parent->i_sb, ea_ino);
++ inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL);
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ ext4_error(parent->i_sb,
+@@ -1486,7 +1486,8 @@ ext4_xattr_inode_cache_find(struct inode
+ }
+
+ while (ce) {
+- ea_inode = ext4_iget(inode->i_sb, ce->e_value);
++ ea_inode = ext4_iget(inode->i_sb, ce->e_value,
++ EXT4_IGET_NORMAL);
+ if (!IS_ERR(ea_inode) &&
+ !is_bad_inode(ea_inode) &&
+ (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) &&
--- /dev/null
+From 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 19 Dec 2018 14:36:58 -0500
+Subject: ext4: check for shutdown and r/o file system in ext4_write_inode()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 upstream.
+
+If the file system has been shut down or is read-only, then
+ext4_write_inode() needs to bail out early.
+
+Also use jbd2_complete_transaction() instead of ext4_force_commit() so
+we only force a commit if it is needed.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5369,9 +5369,13 @@ int ext4_write_inode(struct inode *inode
+ {
+ int err;
+
+- if (WARN_ON_ONCE(current->flags & PF_MEMALLOC))
++ if (WARN_ON_ONCE(current->flags & PF_MEMALLOC) ||
++ sb_rdonly(inode->i_sb))
+ return 0;
+
++ if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
++ return -EIO;
++
+ if (EXT4_SB(inode->i_sb)->s_journal) {
+ if (ext4_journal_current_handle()) {
+ jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
+@@ -5387,7 +5391,8 @@ int ext4_write_inode(struct inode *inode
+ if (wbc->sync_mode != WB_SYNC_ALL || wbc->for_sync)
+ return 0;
+
+- err = ext4_force_commit(inode->i_sb);
++ err = jbd2_complete_transaction(EXT4_SB(inode->i_sb)->s_journal,
++ EXT4_I(inode)->i_sync_tid);
+ } else {
+ struct ext4_iloc iloc;
+
--- /dev/null
+From e647e29196b7f802f8242c39ecb7cc937f5ef217 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?ruippan=20=28=E6=BD=98=E7=9D=BF=29?= <ruippan@tencent.com>
+Date: Tue, 4 Dec 2018 01:04:12 -0500
+Subject: ext4: fix EXT4_IOC_GROUP_ADD ioctl
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: ruippan (潘睿) <ruippan@tencent.com>
+
+commit e647e29196b7f802f8242c39ecb7cc937f5ef217 upstream.
+
+Commit e2b911c53584 ("ext4: clean up feature test macros with
+predicate functions") broke the EXT4_IOC_GROUP_ADD ioctl. This was
+not noticed since only very old versions of resize2fs (before
+e2fsprogs 1.42) use this ioctl. However, using a new kernel with an
+enterprise Linux userspace will cause attempts to use online resize to
+fail with "No reserved GDT blocks".
+
+Fixes: e2b911c53584 ("ext4: clean up feature test macros with predicate...")
+Cc: stable@kernel.org # v4.4
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: ruippan (潘睿) <ruippan@tencent.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1631,7 +1631,7 @@ int ext4_group_add(struct super_block *s
+ }
+
+ if (reserved_gdb || gdb_off == 0) {
+- if (ext4_has_feature_resize_inode(sb) ||
++ if (!ext4_has_feature_resize_inode(sb) ||
+ !le16_to_cpu(es->s_reserved_gdt_blocks)) {
+ ext4_warning(sb,
+ "No reserved GDT blocks, can't resize");
--- /dev/null
+From 61157b24e60fb3cd1f85f2c76a7b1d628f970144 Mon Sep 17 00:00:00 2001
+From: Pan Bian <bianpan2016@163.com>
+Date: Mon, 3 Dec 2018 23:28:02 -0500
+Subject: ext4: fix possible use after free in ext4_quota_enable
+
+From: Pan Bian <bianpan2016@163.com>
+
+commit 61157b24e60fb3cd1f85f2c76a7b1d628f970144 upstream.
+
+The function frees qf_inode via iput but then pass qf_inode to
+lockdep_set_quota_inode on the failure path. This may result in a
+use-after-free bug. The patch frees df_inode only when it is never used.
+
+Fixes: daf647d2dd5 ("ext4: add lockdep annotations for i_data_sem")
+Cc: stable@kernel.org # 4.6
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5712,9 +5712,9 @@ static int ext4_quota_enable(struct supe
+ qf_inode->i_flags |= S_NOQUOTA;
+ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA);
+ err = dquot_enable(qf_inode, type, format_id, flags);
+- iput(qf_inode);
+ if (err)
+ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL);
++ iput(qf_inode);
+
+ return err;
+ }
--- /dev/null
+From fde872682e175743e0c3ef939c89e3c6008a1529 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 19 Dec 2018 14:07:58 -0500
+Subject: ext4: force inode writes when nfsd calls commit_metadata()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit fde872682e175743e0c3ef939c89e3c6008a1529 upstream.
+
+Some time back, nfsd switched from calling vfs_fsync() to using a new
+commit_metadata() hook in export_operations(). If the file system did
+not provide a commit_metadata() hook, it fell back to using
+sync_inode_metadata(). Unfortunately doesn't work on all file
+systems. In particular, it doesn't work on ext4 due to how the inode
+gets journalled --- the VFS writeback code will not always call
+ext4_write_inode().
+
+So we need to provide our own ext4_nfs_commit_metdata() method which
+calls ext4_write_inode() directly.
+
+Google-Bug-Id: 121195940
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 11 +++++++++++
+ include/trace/events/ext4.h | 20 ++++++++++++++++++++
+ 2 files changed, 31 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1202,6 +1202,16 @@ static struct dentry *ext4_fh_to_parent(
+ ext4_nfs_get_inode);
+ }
+
++static int ext4_nfs_commit_metadata(struct inode *inode)
++{
++ struct writeback_control wbc = {
++ .sync_mode = WB_SYNC_ALL
++ };
++
++ trace_ext4_nfs_commit_metadata(inode);
++ return ext4_write_inode(inode, &wbc);
++}
++
+ /*
+ * Try to release metadata pages (indirect blocks, directories) which are
+ * mapped via the block device. Since these pages could have journal heads
+@@ -1406,6 +1416,7 @@ static const struct export_operations ex
+ .fh_to_dentry = ext4_fh_to_dentry,
+ .fh_to_parent = ext4_fh_to_parent,
+ .get_parent = ext4_get_parent,
++ .commit_metadata = ext4_nfs_commit_metadata,
+ };
+
+ enum {
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -225,6 +225,26 @@ TRACE_EVENT(ext4_drop_inode,
+ (unsigned long) __entry->ino, __entry->drop)
+ );
+
++TRACE_EVENT(ext4_nfs_commit_metadata,
++ TP_PROTO(struct inode *inode),
++
++ TP_ARGS(inode),
++
++ TP_STRUCT__entry(
++ __field( dev_t, dev )
++ __field( ino_t, ino )
++ ),
++
++ TP_fast_assign(
++ __entry->dev = inode->i_sb->s_dev;
++ __entry->ino = inode->i_ino;
++ ),
++
++ TP_printk("dev %d,%d ino %lu",
++ MAJOR(__entry->dev), MINOR(__entry->dev),
++ (unsigned long) __entry->ino)
++);
++
+ TRACE_EVENT(ext4_mark_inode_dirty,
+ TP_PROTO(struct inode *inode, unsigned long IP),
+
--- /dev/null
+From a805622a757b6d7f65def4141d29317d8e37b8a1 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 19 Dec 2018 12:28:13 -0500
+Subject: ext4: include terminating u32 in size of xattr entries when expanding inodes
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit a805622a757b6d7f65def4141d29317d8e37b8a1 upstream.
+
+In ext4_expand_extra_isize_ea(), we calculate the total size of the
+xattr header, plus the xattr entries so we know how much of the
+beginning part of the xattrs to move when expanding the inode extra
+size. We need to include the terminating u32 at the end of the xattr
+entries, or else if there is uninitialized, non-zero bytes after the
+xattr entries and before the xattr values, the list of xattr entries
+won't be properly terminated.
+
+Reported-by: Steve Graham <stgraham2000@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2725,7 +2725,7 @@ retry:
+ base = IFIRST(header);
+ end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+ min_offs = end - base;
+- total_ino = sizeof(struct ext4_xattr_ibody_header);
++ total_ino = sizeof(struct ext4_xattr_ibody_header) + sizeof(u32);
+
+ error = xattr_check_inode(inode, header, end);
+ if (error)
--- /dev/null
+From 132d00becb31e88469334e1e62751c81345280e0 Mon Sep 17 00:00:00 2001
+From: Maurizio Lombardi <mlombard@redhat.com>
+Date: Tue, 4 Dec 2018 00:06:53 -0500
+Subject: ext4: missing unlock/put_page() in ext4_try_to_write_inline_data()
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+commit 132d00becb31e88469334e1e62751c81345280e0 upstream.
+
+In case of error, ext4_try_to_write_inline_data() should unlock
+and release the page it holds.
+
+Fixes: f19d5870cbf7 ("ext4: add normal write support for inline data")
+Cc: stable@kernel.org # 3.8
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inline.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -705,8 +705,11 @@ int ext4_try_to_write_inline_data(struct
+
+ if (!PageUptodate(page)) {
+ ret = ext4_read_inline_page(inode, page);
+- if (ret < 0)
++ if (ret < 0) {
++ unlock_page(page);
++ put_page(page);
+ goto out_up_read;
++ }
+ }
+
+ ret = 1;
--- /dev/null
+From e1e71e201703500f708bdeaf64660a2a178cb6a0 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 16 Dec 2018 22:28:50 +0100
+Subject: ocxl: Fix endiannes bug in ocxl_link_update_pe()
+
+From: Greg Kurz <groug@kaod.org>
+
+commit e1e71e201703500f708bdeaf64660a2a178cb6a0 upstream.
+
+All fields in the PE are big-endian. Use cpu_to_be32() like everywhere
+else something is written to the PE. Otherwise a wrong TID will be used
+by the NPU. If this TID happens to point to an existing thread sharing
+the same mm, it could be woken up by error. This is highly improbable
+though. The likely outcome of this is the NPU not finding the target
+thread and forcing the AFU into sending an interrupt, which userspace
+is supposed to handle anyway.
+
+Fixes: e948e06fc63a ("ocxl: Expose the thread_id needed for wait on POWER9")
+Cc: stable@vger.kernel.org # v4.18
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/ocxl/link.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/ocxl/link.c
++++ b/drivers/misc/ocxl/link.c
+@@ -566,7 +566,7 @@ int ocxl_link_update_pe(void *link_handl
+
+ mutex_lock(&spa->spa_lock);
+
+- pe->tid = tid;
++ pe->tid = cpu_to_be32(tid);
+
+ /*
+ * The barrier makes sure the PE is updated
--- /dev/null
+From 2f07229f02d4c55affccd11a61af4fd4b94dc436 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Tue, 11 Dec 2018 18:58:21 +0100
+Subject: ocxl: Fix endiannes bug in read_afu_name()
+
+From: Greg Kurz <groug@kaod.org>
+
+commit 2f07229f02d4c55affccd11a61af4fd4b94dc436 upstream.
+
+The AFU Descriptor Template in the PCI config space has a Name Space
+field which is a 24 Byte ASCII character string of descriptive name
+space for the AFU. The OCXL driver read the string four characters at
+a time with pci_read_config_dword().
+
+This optimization is valid on a little-endian system since this is PCI,
+but a big-endian system ends up with each subset of four characters in
+reverse order.
+
+This could be fixed by switching to read characters one by one. Another
+option is to swap the bytes if we're big-endian.
+
+Go for the latter with le32_to_cpu().
+
+Cc: stable@vger.kernel.org # v4.16
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Acked-by: Frederic Barrat <fbarrat@linux.ibm.com>
+Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/ocxl/config.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/ocxl/config.c
++++ b/drivers/misc/ocxl/config.c
+@@ -318,7 +318,7 @@ static int read_afu_name(struct pci_dev
+ if (rc)
+ return rc;
+ ptr = (u32 *) &afu->name[i];
+- *ptr = val;
++ *ptr = le32_to_cpu((__force __le32) val);
+ }
+ afu->name[OCXL_AFU_NAME_SZ - 1] = '\0'; /* play safe */
+ return 0;
--- /dev/null
+From 804234f27180dcf9a25cb98a88d5212f65b7f3fd Mon Sep 17 00:00:00 2001
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+Date: Tue, 27 Nov 2018 11:45:49 -0300
+Subject: perf env: Also consider env->arch == NULL as local operation
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+commit 804234f27180dcf9a25cb98a88d5212f65b7f3fd upstream.
+
+We'll set a new machine field based on env->arch, which for live mode,
+like with 'perf top' means we need to use uname() to figure the name of
+the arch, fix perf_env__arch() to consider both (env == NULL) and
+(env->arch == NULL) as local operation.
+
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Wang Nan <wangnan0@huawei.com>
+Cc: stable@vger.kernel.org # 4.19
+Link: https://lkml.kernel.org/n/tip-vcz4ufzdon7cwy8dm2ua53xk@git.kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/env.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/perf/util/env.c
++++ b/tools/perf/util/env.c
+@@ -166,7 +166,7 @@ const char *perf_env__arch(struct perf_e
+ struct utsname uts;
+ char *arch_name;
+
+- if (!env) { /* Assume local operation */
++ if (!env || !env->arch) { /* Assume local operation */
+ if (uname(&uts) < 0)
+ return NULL;
+ arch_name = uts.machine;
--- /dev/null
+From ec1891afae740be581ecf5abc8bda74c4549203f Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 6 Nov 2018 23:07:10 +0200
+Subject: perf machine: Record if a arch has a single user/kernel address space
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit ec1891afae740be581ecf5abc8bda74c4549203f upstream.
+
+Some architectures have a single address space for kernel and user
+addresses, which makes it possible to determine if an address is in
+kernel space or user space. Some don't, e.g.: sparc.
+
+Cache that info in perf_env so that, for instance, code needing to
+fallback failed symbol lookups at the kernel space in single address
+space arches can lookup at userspace.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: stable@vger.kernel.org # 4.19
+Link: http://lkml.kernel.org/r/20181106210712.12098-2-adrian.hunter@intel.com
+[ split from a larger patch ]
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/arch/common.c | 10 ++++++++++
+ tools/perf/arch/common.h | 1 +
+ tools/perf/util/machine.h | 1 +
+ tools/perf/util/session.c | 4 ++++
+ 4 files changed, 16 insertions(+)
+
+--- a/tools/perf/arch/common.c
++++ b/tools/perf/arch/common.c
+@@ -200,3 +200,13 @@ int perf_env__lookup_objdump(struct perf
+
+ return perf_env__lookup_binutils_path(env, "objdump", path);
+ }
++
++/*
++ * Some architectures have a single address space for kernel and user addresses,
++ * which makes it possible to determine if an address is in kernel space or user
++ * space.
++ */
++bool perf_env__single_address_space(struct perf_env *env)
++{
++ return strcmp(perf_env__arch(env), "sparc");
++}
+--- a/tools/perf/arch/common.h
++++ b/tools/perf/arch/common.h
+@@ -5,5 +5,6 @@
+ #include "../util/env.h"
+
+ int perf_env__lookup_objdump(struct perf_env *env, const char **path);
++bool perf_env__single_address_space(struct perf_env *env);
+
+ #endif /* ARCH_PERF_COMMON_H */
+--- a/tools/perf/util/machine.h
++++ b/tools/perf/util/machine.h
+@@ -42,6 +42,7 @@ struct machine {
+ u16 id_hdr_size;
+ bool comm_exec;
+ bool kptr_restrict_warned;
++ bool single_address_space;
+ char *root_dir;
+ char *mmap_name;
+ struct threads threads[THREADS__TABLE_SIZE];
+--- a/tools/perf/util/session.c
++++ b/tools/perf/util/session.c
+@@ -24,6 +24,7 @@
+ #include "thread.h"
+ #include "thread-stack.h"
+ #include "stat.h"
++#include "arch/common.h"
+
+ static int perf_session__deliver_event(struct perf_session *session,
+ union perf_event *event,
+@@ -150,6 +151,9 @@ struct perf_session *perf_session__new(s
+ session->machines.host.env = &perf_env;
+ }
+
++ session->machines.host.single_address_space =
++ perf_env__single_address_space(session->machines.host.env);
++
+ if (!data || perf_data__is_write(data)) {
+ /*
+ * In O_RDONLY mode this will be performed when reading the
--- /dev/null
+From 11a64a05dc649815670b1be9fe63d205cb076401 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 11 Nov 2018 18:45:24 +0000
+Subject: perf pmu: Suppress potential format-truncation warning
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 11a64a05dc649815670b1be9fe63d205cb076401 upstream.
+
+Depending on which functions are inlined in util/pmu.c, the snprintf()
+calls in perf_pmu__parse_{scale,unit,per_pkg,snapshot}() might trigger a
+warning:
+
+ util/pmu.c: In function 'pmu_aliases':
+ util/pmu.c:178:31: error: '%s' directive output may be truncated writing up to 255 bytes into a region of size between 0 and 4095 [-Werror=format-truncation=]
+ snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
+ ^~
+
+I found this when trying to build perf from Linux 3.16 with gcc 8.
+However I can reproduce the problem in mainline if I force
+__perf_pmu__new_alias() to be inlined.
+
+Suppress this by using scnprintf() as has been done elsewhere in perf.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: http://lkml.kernel.org/r/20181111184524.fux4taownc6ndbx6@decadent.org.uk
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/pmu.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -145,7 +145,7 @@ static int perf_pmu__parse_scale(struct
+ int fd, ret = -1;
+ char path[PATH_MAX];
+
+- snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
++ scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+@@ -175,7 +175,7 @@ static int perf_pmu__parse_unit(struct p
+ ssize_t sret;
+ int fd;
+
+- snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
++ scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+@@ -205,7 +205,7 @@ perf_pmu__parse_per_pkg(struct perf_pmu_
+ char path[PATH_MAX];
+ int fd;
+
+- snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
++ scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+@@ -223,7 +223,7 @@ static int perf_pmu__parse_snapshot(stru
+ char path[PATH_MAX];
+ int fd;
+
+- snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
++ scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
--- /dev/null
+From 692d0e63324d2954a0c63a812a8588e97023a295 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 6 Nov 2018 23:07:12 +0200
+Subject: perf script: Use fallbacks for branch stacks
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 692d0e63324d2954a0c63a812a8588e97023a295 upstream.
+
+Branch stacks do not necessarily have the same cpumode as the 'ip'. Use
+the fallback functions in those cases.
+
+This patch depends on patch "perf tools: Add fallback functions for cases
+where cpumode is insufficient".
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: stable@vger.kernel.org # 4.19
+Link: http://lkml.kernel.org/r/20181106210712.12098-4-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/builtin-script.c | 12 ++++++------
+ tools/perf/util/scripting-engines/trace-event-python.c | 16 ++++++++--------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/tools/perf/builtin-script.c
++++ b/tools/perf/builtin-script.c
+@@ -727,8 +727,8 @@ static int perf_sample__fprintf_brstack(
+ if (PRINT_FIELD(DSO)) {
+ memset(&alf, 0, sizeof(alf));
+ memset(&alt, 0, sizeof(alt));
+- thread__find_map(thread, sample->cpumode, from, &alf);
+- thread__find_map(thread, sample->cpumode, to, &alt);
++ thread__find_map_fb(thread, sample->cpumode, from, &alf);
++ thread__find_map_fb(thread, sample->cpumode, to, &alt);
+ }
+
+ printed += fprintf(fp, " 0x%"PRIx64, from);
+@@ -774,8 +774,8 @@ static int perf_sample__fprintf_brstacks
+ from = br->entries[i].from;
+ to = br->entries[i].to;
+
+- thread__find_symbol(thread, sample->cpumode, from, &alf);
+- thread__find_symbol(thread, sample->cpumode, to, &alt);
++ thread__find_symbol_fb(thread, sample->cpumode, from, &alf);
++ thread__find_symbol_fb(thread, sample->cpumode, to, &alt);
+
+ printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp);
+ if (PRINT_FIELD(DSO)) {
+@@ -819,11 +819,11 @@ static int perf_sample__fprintf_brstacko
+ from = br->entries[i].from;
+ to = br->entries[i].to;
+
+- if (thread__find_map(thread, sample->cpumode, from, &alf) &&
++ if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
+ !alf.map->dso->adjust_symbols)
+ from = map__map_ip(alf.map, from);
+
+- if (thread__find_map(thread, sample->cpumode, to, &alt) &&
++ if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
+ !alt.map->dso->adjust_symbols)
+ to = map__map_ip(alt.map, to);
+
+--- a/tools/perf/util/scripting-engines/trace-event-python.c
++++ b/tools/perf/util/scripting-engines/trace-event-python.c
+@@ -494,14 +494,14 @@ static PyObject *python_process_brstack(
+ pydict_set_item_string_decref(pyelem, "cycles",
+ PyLong_FromUnsignedLongLong(br->entries[i].flags.cycles));
+
+- thread__find_map(thread, sample->cpumode,
+- br->entries[i].from, &al);
++ thread__find_map_fb(thread, sample->cpumode,
++ br->entries[i].from, &al);
+ dsoname = get_dsoname(al.map);
+ pydict_set_item_string_decref(pyelem, "from_dsoname",
+ _PyUnicode_FromString(dsoname));
+
+- thread__find_map(thread, sample->cpumode,
+- br->entries[i].to, &al);
++ thread__find_map_fb(thread, sample->cpumode,
++ br->entries[i].to, &al);
+ dsoname = get_dsoname(al.map);
+ pydict_set_item_string_decref(pyelem, "to_dsoname",
+ _PyUnicode_FromString(dsoname));
+@@ -576,14 +576,14 @@ static PyObject *python_process_brstacks
+ if (!pyelem)
+ Py_FatalError("couldn't create Python dictionary");
+
+- thread__find_symbol(thread, sample->cpumode,
+- br->entries[i].from, &al);
++ thread__find_symbol_fb(thread, sample->cpumode,
++ br->entries[i].from, &al);
+ get_symoff(al.sym, &al, true, bf, sizeof(bf));
+ pydict_set_item_string_decref(pyelem, "from",
+ _PyUnicode_FromString(bf));
+
+- thread__find_symbol(thread, sample->cpumode,
+- br->entries[i].to, &al);
++ thread__find_symbol_fb(thread, sample->cpumode,
++ br->entries[i].to, &al);
+ get_symoff(al.sym, &al, true, bf, sizeof(bf));
+ pydict_set_item_string_decref(pyelem, "to",
+ _PyUnicode_FromString(bf));
--- /dev/null
+From 8e80ad9983caeee09c3a0a1a37e05bff93becce4 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 6 Nov 2018 23:07:10 +0200
+Subject: perf thread: Add fallback functions for cases where cpumode is insufficient
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 8e80ad9983caeee09c3a0a1a37e05bff93becce4 upstream.
+
+For branch stacks or branch samples, the sample cpumode might not be
+correct because it applies only to the sample 'ip' and not necessary to
+'addr' or branch stack addresses. Add fallback functions that can be
+used to deal with those cases
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: stable@vger.kernel.org # 4.19
+Link: http://lkml.kernel.org/r/20181106210712.12098-2-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/event.c | 27 +++++++++++++++++++++++++++
+ tools/perf/util/machine.c | 27 +++++++++++++++++++++++++++
+ tools/perf/util/machine.h | 2 ++
+ tools/perf/util/thread.h | 4 ++++
+ 4 files changed, 60 insertions(+)
+
+--- a/tools/perf/util/event.c
++++ b/tools/perf/util/event.c
+@@ -1576,6 +1576,24 @@ struct map *thread__find_map(struct thre
+ return al->map;
+ }
+
++/*
++ * For branch stacks or branch samples, the sample cpumode might not be correct
++ * because it applies only to the sample 'ip' and not necessary to 'addr' or
++ * branch stack addresses. If possible, use a fallback to deal with those cases.
++ */
++struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
++ struct addr_location *al)
++{
++ struct map *map = thread__find_map(thread, cpumode, addr, al);
++ struct machine *machine = thread->mg->machine;
++ u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr);
++
++ if (map || addr_cpumode == cpumode)
++ return map;
++
++ return thread__find_map(thread, addr_cpumode, addr, al);
++}
++
+ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
+ u64 addr, struct addr_location *al)
+ {
+@@ -1584,6 +1602,15 @@ struct symbol *thread__find_symbol(struc
+ al->sym = map__find_symbol(al->map, al->addr);
+ return al->sym;
+ }
++
++struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
++ u64 addr, struct addr_location *al)
++{
++ al->sym = NULL;
++ if (thread__find_map_fb(thread, cpumode, addr, al))
++ al->sym = map__find_symbol(al->map, al->addr);
++ return al->sym;
++}
+
+ /*
+ * Callers need to drop the reference to al->thread, obtained in
+--- a/tools/perf/util/machine.c
++++ b/tools/perf/util/machine.c
+@@ -2575,6 +2575,33 @@ int machine__get_kernel_start(struct mac
+ return err;
+ }
+
++u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr)
++{
++ u8 addr_cpumode = cpumode;
++ bool kernel_ip;
++
++ if (!machine->single_address_space)
++ goto out;
++
++ kernel_ip = machine__kernel_ip(machine, addr);
++ switch (cpumode) {
++ case PERF_RECORD_MISC_KERNEL:
++ case PERF_RECORD_MISC_USER:
++ addr_cpumode = kernel_ip ? PERF_RECORD_MISC_KERNEL :
++ PERF_RECORD_MISC_USER;
++ break;
++ case PERF_RECORD_MISC_GUEST_KERNEL:
++ case PERF_RECORD_MISC_GUEST_USER:
++ addr_cpumode = kernel_ip ? PERF_RECORD_MISC_GUEST_KERNEL :
++ PERF_RECORD_MISC_GUEST_USER;
++ break;
++ default:
++ break;
++ }
++out:
++ return addr_cpumode;
++}
++
+ struct dso *machine__findnew_dso(struct machine *machine, const char *filename)
+ {
+ return dsos__findnew(&machine->dsos, filename);
+--- a/tools/perf/util/machine.h
++++ b/tools/perf/util/machine.h
+@@ -100,6 +100,8 @@ static inline bool machine__kernel_ip(st
+ return ip >= kernel_start;
+ }
+
++u8 machine__addr_cpumode(struct machine *machine, u8 cpumode, u64 addr);
++
+ struct thread *machine__find_thread(struct machine *machine, pid_t pid,
+ pid_t tid);
+ struct comm *machine__thread_exec_comm(struct machine *machine,
+--- a/tools/perf/util/thread.h
++++ b/tools/perf/util/thread.h
+@@ -94,9 +94,13 @@ struct thread *thread__main_thread(struc
+
+ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
+ struct addr_location *al);
++struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
++ struct addr_location *al);
+
+ struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
+ u64 addr, struct addr_location *al);
++struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
++ u64 addr, struct addr_location *al);
+
+ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
+ struct addr_location *al);
--- /dev/null
+From 225f99e0c811e23836c4911a2ff147e167dd1fe8 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Tue, 6 Nov 2018 23:07:11 +0200
+Subject: perf tools: Use fallback for sample_addr_correlates_sym() cases
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 225f99e0c811e23836c4911a2ff147e167dd1fe8 upstream.
+
+thread__resolve() is used in the sample_addr_correlates_sym() cases
+where 'addr' is a destination of a branch which does not necessarily
+have the same cpumode as the 'ip'. Use the fallback function in that
+case.
+
+This patch depends on patch "perf tools: Add fallback functions for
+cases where cpumode is insufficient".
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Cc: stable@vger.kernel.org # 4.19
+Link: http://lkml.kernel.org/r/20181106210712.12098-3-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/perf/util/event.c
++++ b/tools/perf/util/event.c
+@@ -1705,7 +1705,7 @@ bool sample_addr_correlates_sym(struct p
+ void thread__resolve(struct thread *thread, struct addr_location *al,
+ struct perf_sample *sample)
+ {
+- thread__find_map(thread, sample->cpumode, sample->addr, al);
++ thread__find_map_fb(thread, sample->cpumode, sample->addr, al);
+
+ al->cpu = sample->cpu;
+ al->sym = NULL;
--- /dev/null
+From 81b1e6e6a8590a19257e37a1633bec098d499c57 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Thu, 11 Oct 2018 11:12:34 +0200
+Subject: platform-msi: Free descriptors in platform_msi_domain_free()
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+commit 81b1e6e6a8590a19257e37a1633bec098d499c57 upstream.
+
+Since the addition of platform MSI support, there were two helpers
+supposed to allocate/free IRQs for a device:
+
+ platform_msi_domain_alloc_irqs()
+ platform_msi_domain_free_irqs()
+
+In these helpers, IRQ descriptors are allocated in the "alloc" routine
+while they are freed in the "free" one.
+
+Later, two other helpers have been added to handle IRQ domains on top
+of MSI domains:
+
+ platform_msi_domain_alloc()
+ platform_msi_domain_free()
+
+Seen from the outside, the logic is pretty close with the former
+helpers and people used it with the same logic as before: a
+platform_msi_domain_alloc() call should be balanced with a
+platform_msi_domain_free() call. While this is probably what was
+intended to do, the platform_msi_domain_free() does not remove/free
+the IRQ descriptor(s) created/inserted in
+platform_msi_domain_alloc().
+
+One effect of such situation is that removing a module that requested
+an IRQ will let one orphaned IRQ descriptor (with an allocated MSI
+entry) in the device descriptors list. Next time the module will be
+inserted back, one will observe that the allocation will happen twice
+in the MSI domain, one time for the remaining descriptor, one time for
+the new one. It also has the side effect to quickly overshoot the
+maximum number of allocated MSI and then prevent any module requesting
+an interrupt in the same domain to be inserted anymore.
+
+This situation has been met with loops of insertion/removal of the
+mvpp2.ko module (requesting 15 MSIs each time).
+
+Fixes: 552c494a7666 ("platform-msi: Allow creation of a MSI-based stacked irq domain")
+Cc: stable@vger.kernel.org
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/platform-msi.c | 6 ++++--
+ include/linux/msi.h | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/platform-msi.c
++++ b/drivers/base/platform-msi.c
+@@ -366,14 +366,16 @@ void platform_msi_domain_free(struct irq
+ unsigned int nvec)
+ {
+ struct platform_msi_priv_data *data = domain->host_data;
+- struct msi_desc *desc;
+- for_each_msi_entry(desc, data->dev) {
++ struct msi_desc *desc, *tmp;
++ for_each_msi_entry_safe(desc, tmp, data->dev) {
+ if (WARN_ON(!desc->irq || desc->nvec_used != 1))
+ return;
+ if (!(desc->irq >= virq && desc->irq < (virq + nvec)))
+ continue;
+
+ irq_domain_free_irqs_common(domain, desc->irq, 1);
++ list_del(&desc->list);
++ free_msi_entry(desc);
+ }
+ }
+
+--- a/include/linux/msi.h
++++ b/include/linux/msi.h
+@@ -116,6 +116,8 @@ struct msi_desc {
+ list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
+ #define for_each_msi_entry(desc, dev) \
+ list_for_each_entry((desc), dev_to_msi_list((dev)), list)
++#define for_each_msi_entry_safe(desc, tmp, dev) \
++ list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
+
+ #ifdef CONFIG_PCI_MSI
+ #define first_pci_msi_entry(pdev) first_msi_entry(&(pdev)->dev)
--- /dev/null
+From e1c3743e1a20647c53b719dbf28b48f45d23f2cd Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Wed, 21 Nov 2018 17:21:09 -0200
+Subject: powerpc/tm: Set MSR[TS] just prior to recheckpoint
+
+From: Breno Leitao <leitao@debian.org>
+
+commit e1c3743e1a20647c53b719dbf28b48f45d23f2cd upstream.
+
+On a signal handler return, the user could set a context with MSR[TS] bits
+set, and these bits would be copied to task regs->msr.
+
+At restore_tm_sigcontexts(), after current task regs->msr[TS] bits are set,
+several __get_user() are called and then a recheckpoint is executed.
+
+This is a problem since a page fault (in kernel space) could happen when
+calling __get_user(). If it happens, the process MSR[TS] bits were
+already set, but recheckpoint was not executed, and SPRs are still invalid.
+
+The page fault can cause the current process to be de-scheduled, with
+MSR[TS] active and without tm_recheckpoint() being called. More
+importantly, without TEXASR[FS] bit set also.
+
+Since TEXASR might not have the FS bit set, and when the process is
+scheduled back, it will try to reclaim, which will be aborted because of
+the CPU is not in the suspended state, and, then, recheckpoint. This
+recheckpoint will restore thread->texasr into TEXASR SPR, which might be
+zero, hitting a BUG_ON().
+
+ kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434!
+ cpu 0xb: Vector: 700 (Program Check) at [c00000041f1576d0]
+ pc: c000000000054550: restore_gprs+0xb0/0x180
+ lr: 0000000000000000
+ sp: c00000041f157950
+ msr: 8000000100021033
+ current = 0xc00000041f143000
+ paca = 0xc00000000fb86300 softe: 0 irq_happened: 0x01
+ pid = 1021, comm = kworker/11:1
+ kernel BUG at /build/linux-sf3Co9/linux-4.9.30/arch/powerpc/kernel/tm.S:434!
+ Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
+ enter ? for help
+ [c00000041f157b30] c00000000001bc3c tm_recheckpoint.part.11+0x6c/0xa0
+ [c00000041f157b70] c00000000001d184 __switch_to+0x1e4/0x4c0
+ [c00000041f157bd0] c00000000082eeb8 __schedule+0x2f8/0x990
+ [c00000041f157cb0] c00000000082f598 schedule+0x48/0xc0
+ [c00000041f157ce0] c0000000000f0d28 worker_thread+0x148/0x610
+ [c00000041f157d80] c0000000000f96b0 kthread+0x120/0x140
+ [c00000041f157e30] c00000000000c0e0 ret_from_kernel_thread+0x5c/0x7c
+
+This patch simply delays the MSR[TS] set, so, if there is any page fault in
+the __get_user() section, it does not have regs->msr[TS] set, since the TM
+structures are still invalid, thus avoiding doing TM operations for
+in-kernel exceptions and possible process reschedule.
+
+With this patch, the MSR[TS] will only be set just before recheckpointing
+and setting TEXASR[FS] = 1, thus avoiding an interrupt with TM registers in
+invalid state.
+
+Other than that, if CONFIG_PREEMPT is set, there might be a preemption just
+after setting MSR[TS] and before tm_recheckpoint(), thus, this block must
+be atomic from a preemption perspective, thus, calling
+preempt_disable/enable() on this code.
+
+It is not possible to move tm_recheckpoint to happen earlier, because it is
+required to get the checkpointed registers from userspace, with
+__get_user(), thus, the only way to avoid this undesired behavior is
+delaying the MSR[TS] set.
+
+The 32-bits signal handler seems to be safe this current issue, but, it
+might be exposed to the preemption issue, thus, disabling preemption in
+this chunk of code.
+
+Changes from v2:
+ * Run the critical section with preempt_disable.
+
+Fixes: 87b4e5393af7 ("powerpc/tm: Fix return of active 64bit signals")
+Cc: stable@vger.kernel.org (v3.9+)
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/signal_32.c | 20 +++++++++++++++++-
+ arch/powerpc/kernel/signal_64.c | 44 +++++++++++++++++++++++++++-------------
+ 2 files changed, 49 insertions(+), 15 deletions(-)
+
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -848,7 +848,23 @@ static long restore_tm_user_regs(struct
+ /* If TM bits are set to the reserved value, it's an invalid context */
+ if (MSR_TM_RESV(msr_hi))
+ return 1;
+- /* Pull in the MSR TM bits from the user context */
++
++ /*
++ * Disabling preemption, since it is unsafe to be preempted
++ * with MSR[TS] set without recheckpointing.
++ */
++ preempt_disable();
++
++ /*
++ * CAUTION:
++ * After regs->MSR[TS] being updated, make sure that get_user(),
++ * put_user() or similar functions are *not* called. These
++ * functions can generate page faults which will cause the process
++ * to be de-scheduled with MSR[TS] set but without calling
++ * tm_recheckpoint(). This can cause a bug.
++ *
++ * Pull in the MSR TM bits from the user context
++ */
+ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
+ /* Now, recheckpoint. This loads up all of the checkpointed (older)
+ * registers, including FP and V[S]Rs. After recheckpointing, the
+@@ -873,6 +889,8 @@ static long restore_tm_user_regs(struct
+ }
+ #endif
+
++ preempt_enable();
++
+ return 0;
+ }
+ #endif
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -467,20 +467,6 @@ static long restore_tm_sigcontexts(struc
+ if (MSR_TM_RESV(msr))
+ return -EINVAL;
+
+- /* pull in MSR TS bits from user context */
+- regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
+-
+- /*
+- * Ensure that TM is enabled in regs->msr before we leave the signal
+- * handler. It could be the case that (a) user disabled the TM bit
+- * through the manipulation of the MSR bits in uc_mcontext or (b) the
+- * TM bit was disabled because a sufficient number of context switches
+- * happened whilst in the signal handler and load_tm overflowed,
+- * disabling the TM bit. In either case we can end up with an illegal
+- * TM state leading to a TM Bad Thing when we return to userspace.
+- */
+- regs->msr |= MSR_TM;
+-
+ /* pull in MSR LE from user context */
+ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
+
+@@ -572,6 +558,34 @@ static long restore_tm_sigcontexts(struc
+ tm_enable();
+ /* Make sure the transaction is marked as failed */
+ tsk->thread.tm_texasr |= TEXASR_FS;
++
++ /*
++ * Disabling preemption, since it is unsafe to be preempted
++ * with MSR[TS] set without recheckpointing.
++ */
++ preempt_disable();
++
++ /* pull in MSR TS bits from user context */
++ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
++
++ /*
++ * Ensure that TM is enabled in regs->msr before we leave the signal
++ * handler. It could be the case that (a) user disabled the TM bit
++ * through the manipulation of the MSR bits in uc_mcontext or (b) the
++ * TM bit was disabled because a sufficient number of context switches
++ * happened whilst in the signal handler and load_tm overflowed,
++ * disabling the TM bit. In either case we can end up with an illegal
++ * TM state leading to a TM Bad Thing when we return to userspace.
++ *
++ * CAUTION:
++ * After regs->MSR[TS] being updated, make sure that get_user(),
++ * put_user() or similar functions are *not* called. These
++ * functions can generate page faults which will cause the process
++ * to be de-scheduled with MSR[TS] set but without calling
++ * tm_recheckpoint(). This can cause a bug.
++ */
++ regs->msr |= MSR_TM;
++
+ /* This loads the checkpointed FP/VEC state, if used */
+ tm_recheckpoint(&tsk->thread);
+
+@@ -585,6 +599,8 @@ static long restore_tm_sigcontexts(struc
+ regs->msr |= MSR_VEC;
+ }
+
++ preempt_enable();
++
+ return err;
+ }
+ #endif
--- /dev/null
+From 6f5b9f018f4c7686fd944d920209d1382d320e4e Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Mon, 26 Nov 2018 18:12:00 -0200
+Subject: powerpc/tm: Unset MSR[TS] if not recheckpointing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Breno Leitao <leitao@debian.org>
+
+commit 6f5b9f018f4c7686fd944d920209d1382d320e4e upstream.
+
+There is a TM Bad Thing bug that can be caused when you return from a
+signal context in a suspended transaction but with ucontext MSR[TS] unset.
+
+This forces regs->msr[TS] to be set at syscall entrance (since the CPU
+state is transactional). It also calls treclaim() to flush the transaction
+state, which is done based on the live (mfmsr) MSR state.
+
+Since user context MSR[TS] is not set, then restore_tm_sigcontexts() is not
+called, thus, not executing recheckpoint, keeping the CPU state as not
+transactional. When calling rfid, SRR1 will have MSR[TS] set, but the CPU
+state is non transactional, causing the TM Bad Thing with the following
+stack:
+
+ [ 33.862316] Bad kernel stack pointer 3fffd9dce3e0 at c00000000000c47c
+ cpu 0x8: Vector: 700 (Program Check) at [c00000003ff7fd40]
+ pc: c00000000000c47c: fast_exception_return+0xac/0xb4
+ lr: 00003fff865f442c
+ sp: 3fffd9dce3e0
+ msr: 8000000102a03031
+ current = 0xc00000041f68b700
+ paca = 0xc00000000fb84800 softe: 0 irq_happened: 0x01
+ pid = 1721, comm = tm-signal-sigre
+ Linux version 4.9.0-3-powerpc64le (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18) ) #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
+ WARNING: exception is not recoverable, can't continue
+
+The same problem happens on 32-bits signal handler, and the fix is very
+similar, if tm_recheckpoint() is not executed, then regs->msr[TS] should be
+zeroed.
+
+This patch also fixes a sparse warning related to lack of indentation when
+CONFIG_PPC_TRANSACTIONAL_MEM is set.
+
+Fixes: 2b0a576d15e0e ("powerpc: Add new transactional memory state to the signal context")
+CC: Stable <stable@vger.kernel.org> # 3.10+
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Tested-by: Michal Suchánek <msuchanek@suse.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/signal_32.c | 18 +++++++++++++-----
+ arch/powerpc/kernel/signal_64.c | 20 ++++++++++++++++----
+ 2 files changed, 29 insertions(+), 9 deletions(-)
+
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -1158,11 +1158,11 @@ SYSCALL_DEFINE0(rt_sigreturn)
+ {
+ struct rt_sigframe __user *rt_sf;
+ struct pt_regs *regs = current_pt_regs();
++ int tm_restore = 0;
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ struct ucontext __user *uc_transact;
+ unsigned long msr_hi;
+ unsigned long tmp;
+- int tm_restore = 0;
+ #endif
+ /* Always make any pending restarted system calls return -EINTR */
+ current->restart_block.fn = do_no_restart_syscall;
+@@ -1210,11 +1210,19 @@ SYSCALL_DEFINE0(rt_sigreturn)
+ goto bad;
+ }
+ }
+- if (!tm_restore)
+- /* Fall through, for non-TM restore */
++ if (!tm_restore) {
++ /*
++ * Unset regs->msr because ucontext MSR TS is not
++ * set, and recheckpoint was not called. This avoid
++ * hitting a TM Bad thing at RFID
++ */
++ regs->msr &= ~MSR_TS_MASK;
++ }
++ /* Fall through, for non-TM restore */
+ #endif
+- if (do_setcontext(&rt_sf->uc, regs, 1))
+- goto bad;
++ if (!tm_restore)
++ if (do_setcontext(&rt_sf->uc, regs, 1))
++ goto bad;
+
+ /*
+ * It's not clear whether or why it is desirable to save the
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -756,11 +756,23 @@ SYSCALL_DEFINE0(rt_sigreturn)
+ &uc_transact->uc_mcontext))
+ goto badframe;
+ }
+- else
+- /* Fall through, for non-TM restore */
+ #endif
+- if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
+- goto badframe;
++ /* Fall through, for non-TM restore */
++ if (!MSR_TM_ACTIVE(msr)) {
++ /*
++ * Unset MSR[TS] on the thread regs since MSR from user
++ * context does not have MSR active, and recheckpoint was
++ * not called since restore_tm_sigcontexts() was not called
++ * also.
++ *
++ * If not unsetting it, the code can RFID to userspace with
++ * MSR[TS] set, but without CPU in the proper state,
++ * causing a TM bad thing.
++ */
++ current->thread.regs->msr &= ~MSR_TS_MASK;
++ if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
++ goto badframe;
++ }
+
+ if (restore_altstack(&uc->uc_stack))
+ goto badframe;
kvm-x86-use-jmp-to-invoke-kvm_spurious_fault-from-.fixup.patch
arm64-kvm-make-vhe-stage-2-tlb-invalidation-operations-non-interruptible.patch
kvm-nvmx-free-the-vmread-vmwrite-bitmaps-if-alloc_kvm_area-fails.patch
+platform-msi-free-descriptors-in-platform_msi_domain_free.patch
+drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch
+drm-udl-get-rid-of-useless-vblank-initialization.patch
+clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch
+perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch
+perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch
+perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch
+perf-script-use-fallbacks-for-branch-stacks.patch
+perf-pmu-suppress-potential-format-truncation-warning.patch
+perf-env-also-consider-env-arch-null-as-local-operation.patch
+ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch
+ocxl-fix-endiannes-bug-in-read_afu_name.patch
+ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch
+ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch
+ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch
+ext4-fix-ext4_ioc_group_add-ioctl.patch
+ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch
+ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch
+ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch
+ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch
+spi-bcm2835-fix-race-on-dma-termination.patch
+spi-bcm2835-fix-book-keeping-of-dma-termination.patch
+spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch
+clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch
+clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch
+crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch
+crypto-chcr-small-packet-tx-stalls-the-queue.patch
+crypto-testmgr-add-aes-cfb-tests.patch
+crypto-cfb-fix-decryption.patch
+cgroup-fix-css_task_iter_procs.patch
+cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch
+btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.patch
+btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch
+btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch
+btrfs-fix-fsync-of-files-with-multiple-hard-links-in-new-directories.patch
+btrfs-run-delayed-items-before-dropping-the-snapshot.patch
+btrfs-send-fix-race-with-transaction-commits-that-create-snapshots.patch
+brcmfmac-fix-roamoff-1-modparam.patch
+brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch
+powerpc-tm-set-msr-just-prior-to-recheckpoint.patch
+powerpc-tm-unset-msr-if-not-recheckpointing.patch
--- /dev/null
+From 56c1723426d3cfd4723bfbfce531d7b38bae6266 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 8 Nov 2018 08:06:10 +0100
+Subject: spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit 56c1723426d3cfd4723bfbfce531d7b38bae6266 upstream.
+
+The IRQ handler bcm2835_spi_interrupt() first reads as much as possible
+from the RX FIFO, then writes as much as possible to the TX FIFO.
+Afterwards it decides whether the transfer is finished by checking if
+the TX FIFO is empty.
+
+If very few bytes were written to the TX FIFO, they may already have
+been transmitted by the time the FIFO's emptiness is checked. As a
+result, the transfer will be declared finished and the chip will be
+reset without reading the corresponding received bytes from the RX FIFO.
+
+The odds of this happening increase with a high clock frequency (such
+that the TX FIFO drains quickly) and either passing "threadirqs" on the
+command line or enabling CONFIG_PREEMPT_RT_BASE (such that the IRQ
+handler may be preempted between filling the TX FIFO and checking its
+emptiness).
+
+Fix by instead checking whether rx_len has reached zero, which means
+that the transfer has been received in full. This is also more
+efficient as it avoids one bus read access per interrupt. Note that
+bcm2835_spi_transfer_one_poll() likewise uses rx_len to determine
+whether the transfer has finished.
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Fixes: e34ff011c70e ("spi: bcm2835: move to the transfer_one driver model")
+Cc: stable@vger.kernel.org # v4.1+
+Cc: Mathias Duckeck <m.duckeck@kunbus.de>
+Cc: Frank Pavlic <f.pavlic@kunbus.de>
+Cc: Martin Sperl <kernel@martin.sperl.org>
+Cc: Noralf Trønnes <noralf@tronnes.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-bcm2835.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -155,8 +155,7 @@ static irqreturn_t bcm2835_spi_interrupt
+ /* Write as many bytes as possible to FIFO */
+ bcm2835_wr_fifo(bs);
+
+- /* based on flags decide if we can finish the transfer */
+- if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) {
++ if (!bs->rx_len) {
+ /* Transfer complete - reset SPI HW */
+ bcm2835_spi_reset_hw(master);
+ /* wake up the framework */
--- /dev/null
+From dbc944115eed48af110646992893dc43321368d8 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 8 Nov 2018 08:06:10 +0100
+Subject: spi: bcm2835: Fix book-keeping of DMA termination
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit dbc944115eed48af110646992893dc43321368d8 upstream.
+
+If submission of a DMA TX transfer succeeds but submission of the
+corresponding RX transfer does not, the BCM2835 SPI driver terminates
+the TX transfer but neglects to reset the dma_pending flag to false.
+
+Thus, if the next transfer uses interrupt mode (because it is shorter
+than BCM2835_SPI_DMA_MIN_LENGTH) and runs into a timeout,
+dmaengine_terminate_all() will be called both for TX (once more) and
+for RX (which was never started in the first place). Fix it.
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions")
+Cc: stable@vger.kernel.org # v4.2+
+Cc: Mathias Duckeck <m.duckeck@kunbus.de>
+Cc: Frank Pavlic <f.pavlic@kunbus.de>
+Cc: Martin Sperl <kernel@martin.sperl.org>
+Cc: Noralf Trønnes <noralf@tronnes.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-bcm2835.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -341,6 +341,7 @@ static int bcm2835_spi_transfer_one_dma(
+ if (ret) {
+ /* need to reset on errors */
+ dmaengine_terminate_all(master->dma_tx);
++ bs->dma_pending = false;
+ bcm2835_spi_reset_hw(master);
+ return ret;
+ }
--- /dev/null
+From e82b0b3828451c1cd331d9f304c6078fcd43b62e Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Thu, 8 Nov 2018 08:06:10 +0100
+Subject: spi: bcm2835: Fix race on DMA termination
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lukas Wunner <lukas@wunner.de>
+
+commit e82b0b3828451c1cd331d9f304c6078fcd43b62e upstream.
+
+If a DMA transfer finishes orderly right when spi_transfer_one_message()
+determines that it has timed out, the callbacks bcm2835_spi_dma_done()
+and bcm2835_spi_handle_err() race to call dmaengine_terminate_all(),
+potentially leading to double termination.
+
+Prevent by atomically changing the dma_pending flag before calling
+dmaengine_terminate_all().
+
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions")
+Cc: stable@vger.kernel.org # v4.2+
+Cc: Mathias Duckeck <m.duckeck@kunbus.de>
+Cc: Frank Pavlic <f.pavlic@kunbus.de>
+Cc: Martin Sperl <kernel@martin.sperl.org>
+Cc: Noralf Trønnes <noralf@tronnes.org>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-bcm2835.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -233,10 +233,9 @@ static void bcm2835_spi_dma_done(void *d
+ * is called the tx-dma must have finished - can't get to this
+ * situation otherwise...
+ */
+- dmaengine_terminate_all(master->dma_tx);
+-
+- /* mark as no longer pending */
+- bs->dma_pending = 0;
++ if (cmpxchg(&bs->dma_pending, true, false)) {
++ dmaengine_terminate_all(master->dma_tx);
++ }
+
+ /* and mark as completed */;
+ complete(&master->xfer_completion);
+@@ -617,10 +616,9 @@ static void bcm2835_spi_handle_err(struc
+ struct bcm2835_spi *bs = spi_master_get_devdata(master);
+
+ /* if an error occurred and we have an active dma, then terminate */
+- if (bs->dma_pending) {
++ if (cmpxchg(&bs->dma_pending, true, false)) {
+ dmaengine_terminate_all(master->dma_tx);
+ dmaengine_terminate_all(master->dma_rx);
+- bs->dma_pending = 0;
+ }
+ /* and reset */
+ bcm2835_spi_reset_hw(master);