From: Greg Kroah-Hartman Date: Sat, 5 Jan 2019 17:41:06 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.9.149~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a6f9e77e4765eba41cb95e8cefa78eefcfeb811;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch brcmfmac-fix-roamoff-1-modparam.patch btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.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 btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch cgroup-fix-css_task_iter_procs.patch clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch crypto-cfb-fix-decryption.patch crypto-chcr-small-packet-tx-stalls-the-queue.patch crypto-testmgr-add-aes-cfb-tests.patch drm-udl-get-rid-of-useless-vblank-initialization.patch drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch ext4-fix-ext4_ioc_group_add-ioctl.patch ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch ocxl-fix-endiannes-bug-in-read_afu_name.patch perf-env-also-consider-env-arch-null-as-local-operation.patch perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch perf-pmu-suppress-potential-format-truncation-warning.patch perf-script-use-fallbacks-for-branch-stacks.patch perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch platform-msi-free-descriptors-in-platform_msi_domain_free.patch powerpc-tm-set-msr-just-prior-to-recheckpoint.patch powerpc-tm-unset-msr-if-not-recheckpointing.patch spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch spi-bcm2835-fix-book-keeping-of-dma-termination.patch spi-bcm2835-fix-race-on-dma-termination.patch --- diff --git a/queue-4.19/brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch b/queue-4.19/brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch new file mode 100644 index 00000000000..9f197eb5d7a --- /dev/null +++ b/queue-4.19/brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch @@ -0,0 +1,116 @@ +From b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Sat, 24 Nov 2018 17:57:05 -0500 +Subject: brcmfmac: Fix out of bounds memory access during fw load + +From: Lyude Paul + +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 +Cc: Pieter-Paul Giesberts +Cc: Franky Lin +Cc: Arend van Spriel +Cc: Kalle Valo +Cc: Arend Van Spriel +Cc: Himanshu Jha +Cc: Dan Haab +Cc: Jia-Shyr Chuang +Cc: Ian Molton +Cc: # v4.17+ +Signed-off-by: Lyude Paul +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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++) { diff --git a/queue-4.19/brcmfmac-fix-roamoff-1-modparam.patch b/queue-4.19/brcmfmac-fix-roamoff-1-modparam.patch new file mode 100644 index 00000000000..6d8becdbebb --- /dev/null +++ b/queue-4.19/brcmfmac-fix-roamoff-1-modparam.patch @@ -0,0 +1,74 @@ +From 8c892df41500469729e0d662816300196e4f463d Mon Sep 17 00:00:00 2001 +From: Stijn Tintel +Date: Tue, 4 Dec 2018 20:29:05 +0200 +Subject: brcmfmac: fix roamoff=1 modparam + +From: Stijn Tintel + +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 # 4.19+ +Signed-off-by: Jonas Gorski +Signed-off-by: Stijn Tintel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.19/btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch b/queue-4.19/btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch new file mode 100644 index 00000000000..3f8e48de7a2 --- /dev/null +++ b/queue-4.19/btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch @@ -0,0 +1,45 @@ +From 05c49e6bc1e8866ecfd674ebeeb58cdbff9145c2 Mon Sep 17 00:00:00 2001 +From: Anand Jain +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 + +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 +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.patch b/queue-4.19/btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.patch new file mode 100644 index 00000000000..a88ee86a263 --- /dev/null +++ b/queue-4.19/btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.patch @@ -0,0 +1,40 @@ +From 0d228ece59a35a9b9e8ff0d40653234a6d90f61e Mon Sep 17 00:00:00 2001 +From: Anand Jain +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 + +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 +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.19/btrfs-fix-fsync-of-files-with-multiple-hard-links-in-new-directories.patch b/queue-4.19/btrfs-fix-fsync-of-files-with-multiple-hard-links-in-new-directories.patch new file mode 100644 index 00000000000..453d9d59dda --- /dev/null +++ b/queue-4.19/btrfs-fix-fsync-of-files-with-multiple-hard-links-in-new-directories.patch @@ -0,0 +1,150 @@ +From 41bd60676923822de1df2c50b3f9a10171f4338a Mon Sep 17 00:00:00 2001 +From: Filipe Manana +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 + +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 + + + +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 +Reported-by: Jayashree Mohan +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ++ * ++ * ++ * 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; diff --git a/queue-4.19/btrfs-run-delayed-items-before-dropping-the-snapshot.patch b/queue-4.19/btrfs-run-delayed-items-before-dropping-the-snapshot.patch new file mode 100644 index 00000000000..9d33e1ee659 --- /dev/null +++ b/queue-4.19/btrfs-run-delayed-items-before-dropping-the-snapshot.patch @@ -0,0 +1,86 @@ +From 0568e82dbe2510fc1fa664f58e5c997d3f1e649e Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Fri, 30 Nov 2018 11:52:14 -0500 +Subject: btrfs: run delayed items before dropping the snapshot + +From: Josef Bacik + +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 +Signed-off-by: Josef Bacik +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.19/btrfs-send-fix-race-with-transaction-commits-that-create-snapshots.patch b/queue-4.19/btrfs-send-fix-race-with-transaction-commits-that-create-snapshots.patch new file mode 100644 index 00000000000..c16baab3bde --- /dev/null +++ b/queue-4.19/btrfs-send-fix-race-with-transaction-commits-that-create-snapshots.patch @@ -0,0 +1,145 @@ +From be6821f82c3cc36e026f5afd10249988852b35ea Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Tue, 11 Dec 2018 10:19:45 +0000 +Subject: Btrfs: send, fix race with transaction commits that create snapshots + +From: Filipe Manana + +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 +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.19/btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch b/queue-4.19/btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch new file mode 100644 index 00000000000..e3cefa59fec --- /dev/null +++ b/queue-4.19/btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch @@ -0,0 +1,71 @@ +From 27a7ff554e8d349627a90bda275c527b7348adae Mon Sep 17 00:00:00 2001 +From: Lu Fengqi +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 + +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 +Signed-off-by: Lu Fengqi +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch b/queue-4.19/cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch new file mode 100644 index 00000000000..9e5dcea1299 --- /dev/null +++ b/queue-4.19/cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch @@ -0,0 +1,80 @@ +From eafb27fa5283599ce6c5492ea18cf636a28222bb Mon Sep 17 00:00:00 2001 +From: Macpaul Lin +Date: Wed, 19 Dec 2018 12:11:03 +0800 +Subject: cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader. + +From: Macpaul Lin + +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 +Cc: stable@vger.kernel.org +Reviewed-by: Johan Hovold +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/cgroup-fix-css_task_iter_procs.patch b/queue-4.19/cgroup-fix-css_task_iter_procs.patch new file mode 100644 index 00000000000..3f85c26cc83 --- /dev/null +++ b/queue-4.19/cgroup-fix-css_task_iter_procs.patch @@ -0,0 +1,120 @@ +From e9d81a1bc2c48ea9782e3e8b53875f419766ef47 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Thu, 8 Nov 2018 12:15:15 -0800 +Subject: cgroup: fix CSS_TASK_ITER_PROCS + +From: Tejun Heo + +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 +Reported-by: "Michael Kerrisk (man-pages)" +Fixes: 8cfd8147df67 ("cgroup: implement cgroup v2 thread support") +Cc: stable@vger.kernel.org # v4.14+ +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } diff --git a/queue-4.19/clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch b/queue-4.19/clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch new file mode 100644 index 00000000000..c828127b5b7 --- /dev/null +++ b/queue-4.19/clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch @@ -0,0 +1,34 @@ +From 8b19faf6fae2867e2c177212c541e8ae36aa4d32 Mon Sep 17 00:00:00 2001 +From: Johan Jonker +Date: Sat, 3 Nov 2018 23:54:13 +0100 +Subject: clk: rockchip: fix typo in rk3188 spdif_frac parent + +From: Johan Jonker + +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 +Acked-by: Elaine Zhang +Signed-off-by: Heiko Stuebner +Signed-off-by: Greg Kroah-Hartman + +--- + 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), diff --git a/queue-4.19/clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch b/queue-4.19/clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch new file mode 100644 index 00000000000..9b31c239adb --- /dev/null +++ b/queue-4.19/clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch @@ -0,0 +1,76 @@ +From 65b6657672388b72822e0367f06d41c1e3ffb5bb Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 4 Nov 2018 19:26:40 +0100 +Subject: clk: sunxi-ng: Use u64 for calculation of NM rate + +From: Jernej Skrabec + +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: +Signed-off-by: Jernej Skrabec +Signed-off-by: Maxime Ripard +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch b/queue-4.19/clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch new file mode 100644 index 00000000000..b2f882a4883 --- /dev/null +++ b/queue-4.19/clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch @@ -0,0 +1,174 @@ +From bf287607c80f24387fedb431a346dc67f25be12c Mon Sep 17 00:00:00 2001 +From: Alexey Brodkin +Date: Mon, 19 Nov 2018 14:29:17 +0300 +Subject: clocksource/drivers/arc_timer: Utilize generic sched_clock + +From: Alexey Brodkin + +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 +Cc: Daniel Lezcano +Cc: Vineet Gupta +Cc: Thomas Gleixner +Cc: stable@vger.kernel.org +Acked-by: Vineet Gupta +Signed-off-by: Daniel Lezcano +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #include + #include +@@ -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); + } + diff --git a/queue-4.19/crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch b/queue-4.19/crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch new file mode 100644 index 00000000000..49ecf6a8afe --- /dev/null +++ b/queue-4.19/crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch @@ -0,0 +1,149 @@ +From 7172122be6a4712d699da4d261f92aa5ab3a78b8 Mon Sep 17 00:00:00 2001 +From: Wenwen Wang +Date: Thu, 18 Oct 2018 19:50:43 -0500 +Subject: crypto: cavium/nitrox - fix a DMA pool free failure + +From: Wenwen Wang + +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: +Signed-off-by: Wenwen Wang +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 { diff --git a/queue-4.19/crypto-cfb-fix-decryption.patch b/queue-4.19/crypto-cfb-fix-decryption.patch new file mode 100644 index 00000000000..12495bf41ec --- /dev/null +++ b/queue-4.19/crypto-cfb-fix-decryption.patch @@ -0,0 +1,33 @@ +From fa4600734b74f74d9169c3015946d4722f8bcf79 Mon Sep 17 00:00:00 2001 +From: Dmitry Eremin-Solenikov +Date: Sat, 20 Oct 2018 02:01:52 +0300 +Subject: crypto: cfb - fix decryption + +From: Dmitry Eremin-Solenikov + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/crypto-chcr-small-packet-tx-stalls-the-queue.patch b/queue-4.19/crypto-chcr-small-packet-tx-stalls-the-queue.patch new file mode 100644 index 00000000000..ec157ef5790 --- /dev/null +++ b/queue-4.19/crypto-chcr-small-packet-tx-stalls-the-queue.patch @@ -0,0 +1,37 @@ +From c35828ea906a7c76632a0211e59c392903cd4615 Mon Sep 17 00:00:00 2001 +From: Atul Gupta +Date: Fri, 30 Nov 2018 14:31:48 +0530 +Subject: crypto: chcr - small packet Tx stalls the queue + +From: Atul Gupta + +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 +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/crypto-testmgr-add-aes-cfb-tests.patch b/queue-4.19/crypto-testmgr-add-aes-cfb-tests.patch new file mode 100644 index 00000000000..6ed5cbb5bb0 --- /dev/null +++ b/queue-4.19/crypto-testmgr-add-aes-cfb-tests.patch @@ -0,0 +1,145 @@ +From 7da66670775d201f633577f5b15a4bbeebaaa2b0 Mon Sep 17 00:00:00 2001 +From: Dmitry Eremin-Solenikov +Date: Sat, 20 Oct 2018 02:01:53 +0300 +Subject: crypto: testmgr - add AES-CFB tests + +From: Dmitry Eremin-Solenikov + +commit 7da66670775d201f633577f5b15a4bbeebaaa2b0 upstream. + +Add AES128/192/256-CFB testvectors from NIST SP800-38A. + +Signed-off-by: Dmitry Eremin-Solenikov +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Eremin-Solenikov +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.19/drm-udl-get-rid-of-useless-vblank-initialization.patch b/queue-4.19/drm-udl-get-rid-of-useless-vblank-initialization.patch new file mode 100644 index 00000000000..eed4e4d4678 --- /dev/null +++ b/queue-4.19/drm-udl-get-rid-of-useless-vblank-initialization.patch @@ -0,0 +1,47 @@ +From 32e932e37e6b6e13b66add307192c7ddd40a781d Mon Sep 17 00:00:00 2001 +From: Eugeniy Paltsev +Date: Fri, 28 Sep 2018 17:41:26 +0300 +Subject: DRM: UDL: get rid of useless vblank initialization + +From: Eugeniy Paltsev + +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 +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20180928144126.21598-1-Eugeniy.Paltsev@synopsys.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.19/drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch b/queue-4.19/drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch new file mode 100644 index 00000000000..02fe152148d --- /dev/null +++ b/queue-4.19/drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch @@ -0,0 +1,42 @@ +From 2f20fa8d12e859a03f68bdd81d75830141bc9ac9 Mon Sep 17 00:00:00 2001 +From: Eric Anholt +Date: Fri, 28 Sep 2018 16:21:26 -0700 +Subject: drm/v3d: Skip debugfs dumping GCA on platforms without GCA. + +From: Eric Anholt + +commit 2f20fa8d12e859a03f68bdd81d75830141bc9ac9 upstream. + +Fixes an oops reading this debugfs entry on BCM7278. + +Signed-off-by: Eric Anholt +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: +Reviewed-by: Boris Brezillon +Signed-off-by: Greg Kroah-Hartman + +--- + 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++) { diff --git a/queue-4.19/ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch b/queue-4.19/ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch new file mode 100644 index 00000000000..95d232c9e1b --- /dev/null +++ b/queue-4.19/ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch @@ -0,0 +1,501 @@ +From fb265c9cb49e2074ddcdd4de99728aefdd3b3592 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 25 Nov 2018 17:20:31 -0500 +Subject: ext4: add ext4_sb_bread() to disambiguate ENOMEM cases + +From: Theodore Ts'o + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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) { diff --git a/queue-4.19/ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch b/queue-4.19/ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch new file mode 100644 index 00000000000..8a89dbfe23d --- /dev/null +++ b/queue-4.19/ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch @@ -0,0 +1,339 @@ +From 8a363970d1dc38c4ec4ad575c862f776f468d057 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 19 Dec 2018 12:29:13 -0500 +Subject: ext4: avoid declaring fs inconsistent due to invalid file handles + +From: Theodore Ts'o + +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 + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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) && diff --git a/queue-4.19/ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch b/queue-4.19/ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch new file mode 100644 index 00000000000..15817842f10 --- /dev/null +++ b/queue-4.19/ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch @@ -0,0 +1,50 @@ +From 18f2c4fcebf2582f96cbd5f2238f4f354a0e4847 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.19/ext4-fix-ext4_ioc_group_add-ioctl.patch b/queue-4.19/ext4-fix-ext4_ioc_group_add-ioctl.patch new file mode 100644 index 00000000000..311c91efd37 --- /dev/null +++ b/queue-4.19/ext4-fix-ext4_ioc_group_add-ioctl.patch @@ -0,0 +1,40 @@ +From e647e29196b7f802f8242c39ecb7cc937f5ef217 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?ruippan=20=28=E6=BD=98=E7=9D=BF=29?= +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 (潘睿) + +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 +Signed-off-by: ruippan (潘睿) +Signed-off-by: Greg Kroah-Hartman + +--- + 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"); diff --git a/queue-4.19/ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch b/queue-4.19/ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch new file mode 100644 index 00000000000..9421a5d544f --- /dev/null +++ b/queue-4.19/ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch @@ -0,0 +1,37 @@ +From 61157b24e60fb3cd1f85f2c76a7b1d628f970144 Mon Sep 17 00:00:00 2001 +From: Pan Bian +Date: Mon, 3 Dec 2018 23:28:02 -0500 +Subject: ext4: fix possible use after free in ext4_quota_enable + +From: Pan Bian + +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 +Signed-off-by: Pan Bian +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.19/ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch b/queue-4.19/ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch new file mode 100644 index 00000000000..eab20ed13e1 --- /dev/null +++ b/queue-4.19/ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch @@ -0,0 +1,86 @@ +From fde872682e175743e0c3ef939c89e3c6008a1529 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 19 Dec 2018 14:07:58 -0500 +Subject: ext4: force inode writes when nfsd calls commit_metadata() + +From: Theodore Ts'o + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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), + diff --git a/queue-4.19/ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch b/queue-4.19/ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch new file mode 100644 index 00000000000..1557f2cadfc --- /dev/null +++ b/queue-4.19/ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch @@ -0,0 +1,37 @@ +From a805622a757b6d7f65def4141d29317d8e37b8a1 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch b/queue-4.19/ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch new file mode 100644 index 00000000000..a9c034f6c3a --- /dev/null +++ b/queue-4.19/ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch @@ -0,0 +1,37 @@ +From 132d00becb31e88469334e1e62751c81345280e0 Mon Sep 17 00:00:00 2001 +From: Maurizio Lombardi +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 + +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 +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch b/queue-4.19/ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch new file mode 100644 index 00000000000..52da991750c --- /dev/null +++ b/queue-4.19/ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch @@ -0,0 +1,39 @@ +From e1e71e201703500f708bdeaf64660a2a178cb6a0 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Sun, 16 Dec 2018 22:28:50 +0100 +Subject: ocxl: Fix endiannes bug in ocxl_link_update_pe() + +From: Greg Kurz + +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 +Acked-by: Andrew Donnellan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.19/ocxl-fix-endiannes-bug-in-read_afu_name.patch b/queue-4.19/ocxl-fix-endiannes-bug-in-read_afu_name.patch new file mode 100644 index 00000000000..8fce418a4bb --- /dev/null +++ b/queue-4.19/ocxl-fix-endiannes-bug-in-read_afu_name.patch @@ -0,0 +1,45 @@ +From 2f07229f02d4c55affccd11a61af4fd4b94dc436 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Tue, 11 Dec 2018 18:58:21 +0100 +Subject: ocxl: Fix endiannes bug in read_afu_name() + +From: Greg Kurz + +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 +Acked-by: Frederic Barrat +Acked-by: Andrew Donnellan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/perf-env-also-consider-env-arch-null-as-local-operation.patch b/queue-4.19/perf-env-also-consider-env-arch-null-as-local-operation.patch new file mode 100644 index 00000000000..3b7e135ae68 --- /dev/null +++ b/queue-4.19/perf-env-also-consider-env-arch-null-as-local-operation.patch @@ -0,0 +1,43 @@ +From 804234f27180dcf9a25cb98a88d5212f65b7f3fd Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +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 + +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 +Cc: Andi Kleen +Cc: David Ahern +Cc: David S. Miller +Cc: Jiri Olsa +Cc: Leo Yan +Cc: Mathieu Poirier +Cc: Namhyung Kim +Cc: Wang Nan +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch b/queue-4.19/perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch new file mode 100644 index 00000000000..6efe29bf606 --- /dev/null +++ b/queue-4.19/perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch @@ -0,0 +1,91 @@ +From ec1891afae740be581ecf5abc8bda74c4549203f Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +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 + +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 +Cc: Andi Kleen +Cc: David S. Miller +Cc: Jiri Olsa +Cc: Leo Yan +Cc: Mathieu Poirier +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.19/perf-pmu-suppress-potential-format-truncation-warning.patch b/queue-4.19/perf-pmu-suppress-potential-format-truncation-warning.patch new file mode 100644 index 00000000000..c9d73db0745 --- /dev/null +++ b/queue-4.19/perf-pmu-suppress-potential-format-truncation-warning.patch @@ -0,0 +1,76 @@ +From 11a64a05dc649815670b1be9fe63d205cb076401 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sun, 11 Nov 2018 18:45:24 +0000 +Subject: perf pmu: Suppress potential format-truncation warning + +From: Ben Hutchings + +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 +Cc: Alexander Shishkin +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/20181111184524.fux4taownc6ndbx6@decadent.org.uk +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/perf-script-use-fallbacks-for-branch-stacks.patch b/queue-4.19/perf-script-use-fallbacks-for-branch-stacks.patch new file mode 100644 index 00000000000..4d3511c5f55 --- /dev/null +++ b/queue-4.19/perf-script-use-fallbacks-for-branch-stacks.patch @@ -0,0 +1,109 @@ +From 692d0e63324d2954a0c63a812a8588e97023a295 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Tue, 6 Nov 2018 23:07:12 +0200 +Subject: perf script: Use fallbacks for branch stacks + +From: Adrian Hunter + +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 +Cc: Andi Kleen +Cc: David S. Miller +Cc: Jiri Olsa +Cc: Leo Yan +Cc: Mathieu Poirier +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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)); diff --git a/queue-4.19/perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch b/queue-4.19/perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch new file mode 100644 index 00000000000..401262ed729 --- /dev/null +++ b/queue-4.19/perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch @@ -0,0 +1,138 @@ +From 8e80ad9983caeee09c3a0a1a37e05bff93becce4 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Tue, 6 Nov 2018 23:07:10 +0200 +Subject: perf thread: Add fallback functions for cases where cpumode is insufficient + +From: Adrian Hunter + +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 +Cc: Andi Kleen +Cc: David S. Miller +Cc: Jiri Olsa +Cc: Leo Yan +Cc: Mathieu Poirier +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.19/perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch b/queue-4.19/perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch new file mode 100644 index 00000000000..2d53e0a3eda --- /dev/null +++ b/queue-4.19/perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch @@ -0,0 +1,43 @@ +From 225f99e0c811e23836c4911a2ff147e167dd1fe8 Mon Sep 17 00:00:00 2001 +From: Adrian Hunter +Date: Tue, 6 Nov 2018 23:07:11 +0200 +Subject: perf tools: Use fallback for sample_addr_correlates_sym() cases + +From: Adrian Hunter + +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 +Cc: Andi Kleen +Cc: David S. Miller +Cc: Jiri Olsa +Cc: Leo Yan +Cc: Mathieu Poirier +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/platform-msi-free-descriptors-in-platform_msi_domain_free.patch b/queue-4.19/platform-msi-free-descriptors-in-platform_msi_domain_free.patch new file mode 100644 index 00000000000..50843daf86d --- /dev/null +++ b/queue-4.19/platform-msi-free-descriptors-in-platform_msi_domain_free.patch @@ -0,0 +1,87 @@ +From 81b1e6e6a8590a19257e37a1633bec098d499c57 Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Thu, 11 Oct 2018 11:12:34 +0200 +Subject: platform-msi: Free descriptors in platform_msi_domain_free() + +From: Miquel Raynal + +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 +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-4.19/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch b/queue-4.19/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch new file mode 100644 index 00000000000..fbf5897beda --- /dev/null +++ b/queue-4.19/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch @@ -0,0 +1,189 @@ +From e1c3743e1a20647c53b719dbf28b48f45d23f2cd Mon Sep 17 00:00:00 2001 +From: Breno Leitao +Date: Wed, 21 Nov 2018 17:21:09 -0200 +Subject: powerpc/tm: Set MSR[TS] just prior to recheckpoint + +From: Breno Leitao + +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 +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-4.19/powerpc-tm-unset-msr-if-not-recheckpointing.patch b/queue-4.19/powerpc-tm-unset-msr-if-not-recheckpointing.patch new file mode 100644 index 00000000000..13d4c0ad781 --- /dev/null +++ b/queue-4.19/powerpc-tm-unset-msr-if-not-recheckpointing.patch @@ -0,0 +1,125 @@ +From 6f5b9f018f4c7686fd944d920209d1382d320e4e Mon Sep 17 00:00:00 2001 +From: Breno Leitao +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 + +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 # 3.10+ +Signed-off-by: Breno Leitao +Tested-by: Michal Suchánek +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/series b/queue-4.19/series index f2ed120d27a..967bd015643 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -92,3 +92,44 @@ x86-mm-drop-usage-of-__flush_tlb_all-in-kernel_physical_mapping_init.patch 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 diff --git a/queue-4.19/spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch b/queue-4.19/spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch new file mode 100644 index 00000000000..de1346e5611 --- /dev/null +++ b/queue-4.19/spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch @@ -0,0 +1,60 @@ +From 56c1723426d3cfd4723bfbfce531d7b38bae6266 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +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 + +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 +Fixes: e34ff011c70e ("spi: bcm2835: move to the transfer_one driver model") +Cc: stable@vger.kernel.org # v4.1+ +Cc: Mathias Duckeck +Cc: Frank Pavlic +Cc: Martin Sperl +Cc: Noralf Trønnes +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-4.19/spi-bcm2835-fix-book-keeping-of-dma-termination.patch b/queue-4.19/spi-bcm2835-fix-book-keeping-of-dma-termination.patch new file mode 100644 index 00000000000..25145cb588e --- /dev/null +++ b/queue-4.19/spi-bcm2835-fix-book-keeping-of-dma-termination.patch @@ -0,0 +1,45 @@ +From dbc944115eed48af110646992893dc43321368d8 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +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 + +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 +Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions") +Cc: stable@vger.kernel.org # v4.2+ +Cc: Mathias Duckeck +Cc: Frank Pavlic +Cc: Martin Sperl +Cc: Noralf Trønnes +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.19/spi-bcm2835-fix-race-on-dma-termination.patch b/queue-4.19/spi-bcm2835-fix-race-on-dma-termination.patch new file mode 100644 index 00000000000..647b30fd636 --- /dev/null +++ b/queue-4.19/spi-bcm2835-fix-race-on-dma-termination.patch @@ -0,0 +1,62 @@ +From e82b0b3828451c1cd331d9f304c6078fcd43b62e Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +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 + +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 +Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions") +Cc: stable@vger.kernel.org # v4.2+ +Cc: Mathias Duckeck +Cc: Frank Pavlic +Cc: Martin Sperl +Cc: Noralf Trønnes +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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);