]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Jan 2019 17:41:06 +0000 (18:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Jan 2019 17:41:06 +0000 (18:41 +0100)
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

42 files changed:
queue-4.19/brcmfmac-fix-out-of-bounds-memory-access-during-fw-load.patch [new file with mode: 0644]
queue-4.19/brcmfmac-fix-roamoff-1-modparam.patch [new file with mode: 0644]
queue-4.19/btrfs-dev-replace-go-back-to-suspend-state-if-another-excl_op-is-running.patch [new file with mode: 0644]
queue-4.19/btrfs-dev-replace-go-back-to-suspended-state-if-target-device-is-missing.patch [new file with mode: 0644]
queue-4.19/btrfs-fix-fsync-of-files-with-multiple-hard-links-in-new-directories.patch [new file with mode: 0644]
queue-4.19/btrfs-run-delayed-items-before-dropping-the-snapshot.patch [new file with mode: 0644]
queue-4.19/btrfs-send-fix-race-with-transaction-commits-that-create-snapshots.patch [new file with mode: 0644]
queue-4.19/btrfs-skip-file_extent-generation-check-for-free_space_inode-in-run_delalloc_nocow.patch [new file with mode: 0644]
queue-4.19/cdc-acm-fix-abnormal-data-rx-issue-for-mediatek-preloader.patch [new file with mode: 0644]
queue-4.19/cgroup-fix-css_task_iter_procs.patch [new file with mode: 0644]
queue-4.19/clk-rockchip-fix-typo-in-rk3188-spdif_frac-parent.patch [new file with mode: 0644]
queue-4.19/clk-sunxi-ng-use-u64-for-calculation-of-nm-rate.patch [new file with mode: 0644]
queue-4.19/clocksource-drivers-arc_timer-utilize-generic-sched_clock.patch [new file with mode: 0644]
queue-4.19/crypto-cavium-nitrox-fix-a-dma-pool-free-failure.patch [new file with mode: 0644]
queue-4.19/crypto-cfb-fix-decryption.patch [new file with mode: 0644]
queue-4.19/crypto-chcr-small-packet-tx-stalls-the-queue.patch [new file with mode: 0644]
queue-4.19/crypto-testmgr-add-aes-cfb-tests.patch [new file with mode: 0644]
queue-4.19/drm-udl-get-rid-of-useless-vblank-initialization.patch [new file with mode: 0644]
queue-4.19/drm-v3d-skip-debugfs-dumping-gca-on-platforms-without-gca.patch [new file with mode: 0644]
queue-4.19/ext4-add-ext4_sb_bread-to-disambiguate-enomem-cases.patch [new file with mode: 0644]
queue-4.19/ext4-avoid-declaring-fs-inconsistent-due-to-invalid-file-handles.patch [new file with mode: 0644]
queue-4.19/ext4-check-for-shutdown-and-r-o-file-system-in-ext4_write_inode.patch [new file with mode: 0644]
queue-4.19/ext4-fix-ext4_ioc_group_add-ioctl.patch [new file with mode: 0644]
queue-4.19/ext4-fix-possible-use-after-free-in-ext4_quota_enable.patch [new file with mode: 0644]
queue-4.19/ext4-force-inode-writes-when-nfsd-calls-commit_metadata.patch [new file with mode: 0644]
queue-4.19/ext4-include-terminating-u32-in-size-of-xattr-entries-when-expanding-inodes.patch [new file with mode: 0644]
queue-4.19/ext4-missing-unlock-put_page-in-ext4_try_to_write_inline_data.patch [new file with mode: 0644]
queue-4.19/ocxl-fix-endiannes-bug-in-ocxl_link_update_pe.patch [new file with mode: 0644]
queue-4.19/ocxl-fix-endiannes-bug-in-read_afu_name.patch [new file with mode: 0644]
queue-4.19/perf-env-also-consider-env-arch-null-as-local-operation.patch [new file with mode: 0644]
queue-4.19/perf-machine-record-if-a-arch-has-a-single-user-kernel-address-space.patch [new file with mode: 0644]
queue-4.19/perf-pmu-suppress-potential-format-truncation-warning.patch [new file with mode: 0644]
queue-4.19/perf-script-use-fallbacks-for-branch-stacks.patch [new file with mode: 0644]
queue-4.19/perf-thread-add-fallback-functions-for-cases-where-cpumode-is-insufficient.patch [new file with mode: 0644]
queue-4.19/perf-tools-use-fallback-for-sample_addr_correlates_sym-cases.patch [new file with mode: 0644]
queue-4.19/platform-msi-free-descriptors-in-platform_msi_domain_free.patch [new file with mode: 0644]
queue-4.19/powerpc-tm-set-msr-just-prior-to-recheckpoint.patch [new file with mode: 0644]
queue-4.19/powerpc-tm-unset-msr-if-not-recheckpointing.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/spi-bcm2835-avoid-finishing-transfer-prematurely-in-irq-mode.patch [new file with mode: 0644]
queue-4.19/spi-bcm2835-fix-book-keeping-of-dma-termination.patch [new file with mode: 0644]
queue-4.19/spi-bcm2835-fix-race-on-dma-termination.patch [new file with mode: 0644]

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