]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Sep 2020 16:22:36 +0000 (18:22 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Sep 2020 16:22:36 +0000 (18:22 +0200)
added patches:
arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch
btrfs-allocate-scrub-workqueues-outside-of-locks.patch
btrfs-drop-path-before-adding-new-uuid-tree-entry.patch
btrfs-set-the-correct-lockdep-class-for-new-nodes.patch
btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch
btrfs-tree-checker-fix-the-error-message-for-transid-error.patch
ext2-don-t-update-mtime-on-cow-faults.patch
iommu-vt-d-handle-36bit-addressing-for-x86-32.patch
tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch
xfs-don-t-update-mtime-on-cow-faults.patch

queue-5.4/arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch [new file with mode: 0644]
queue-5.4/btrfs-allocate-scrub-workqueues-outside-of-locks.patch [new file with mode: 0644]
queue-5.4/btrfs-drop-path-before-adding-new-uuid-tree-entry.patch [new file with mode: 0644]
queue-5.4/btrfs-set-the-correct-lockdep-class-for-new-nodes.patch [new file with mode: 0644]
queue-5.4/btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch [new file with mode: 0644]
queue-5.4/btrfs-tree-checker-fix-the-error-message-for-transid-error.patch [new file with mode: 0644]
queue-5.4/ext2-don-t-update-mtime-on-cow-faults.patch [new file with mode: 0644]
queue-5.4/iommu-vt-d-handle-36bit-addressing-for-x86-32.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch [new file with mode: 0644]
queue-5.4/xfs-don-t-update-mtime-on-cow-faults.patch [new file with mode: 0644]

diff --git a/queue-5.4/arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch b/queue-5.4/arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch
new file mode 100644 (file)
index 0000000..7236b8c
--- /dev/null
@@ -0,0 +1,73 @@
+From feb92d7d3813456c11dce215b3421801a78a8986 Mon Sep 17 00:00:00 2001
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Sun, 26 Jul 2020 21:51:59 -0700
+Subject: ARC: perf: don't bail setup if pct irq missing in device-tree
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+commit feb92d7d3813456c11dce215b3421801a78a8986 upstream.
+
+Current code inadventely bails if hardware supports sampling/overflow
+interrupts, but the irq is missing from device tree.
+
+|
+| # perf stat -e cycles,instructions,major-faults,minor-faults ../hackbench
+| Running with 10 groups 400 process
+| Time: 0.921
+|
+| Performance counter stats for '../hackbench':
+|
+|   <not supported>      cycles
+|   <not supported>      instructions
+|                 0      major-faults
+|              8679      minor-faults
+
+This need not be as we can still do simple counting based perf stat.
+This unborks perf on HSDK-4xD
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/kernel/perf_event.c |   14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/arch/arc/kernel/perf_event.c
++++ b/arch/arc/kernel/perf_event.c
+@@ -562,7 +562,7 @@ static int arc_pmu_device_probe(struct p
+ {
+       struct arc_reg_pct_build pct_bcr;
+       struct arc_reg_cc_build cc_bcr;
+-      int i, has_interrupts;
++      int i, has_interrupts, irq;
+       int counter_size;       /* in bits */
+       union cc_name {
+@@ -637,13 +637,7 @@ static int arc_pmu_device_probe(struct p
+               .attr_groups    = arc_pmu->attr_groups,
+       };
+-      if (has_interrupts) {
+-              int irq = platform_get_irq(pdev, 0);
+-
+-              if (irq < 0) {
+-                      pr_err("Cannot get IRQ number for the platform\n");
+-                      return -ENODEV;
+-              }
++      if (has_interrupts && (irq = platform_get_irq(pdev, 0) >= 0)) {
+               arc_pmu->irq = irq;
+@@ -652,9 +646,9 @@ static int arc_pmu_device_probe(struct p
+                                  this_cpu_ptr(&arc_pmu_cpu));
+               on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1);
+-
+-      } else
++      } else {
+               arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
++      }
+       /*
+        * perf parser doesn't really like '-' symbol in events name, so let's
diff --git a/queue-5.4/btrfs-allocate-scrub-workqueues-outside-of-locks.patch b/queue-5.4/btrfs-allocate-scrub-workqueues-outside-of-locks.patch
new file mode 100644 (file)
index 0000000..f8d776c
--- /dev/null
@@ -0,0 +1,407 @@
+From e89c4a9c8e6ce3a84cab4f342687d3fbbb1234eb Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:29 -0400
+Subject: btrfs: allocate scrub workqueues outside of locks
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit e89c4a9c8e6ce3a84cab4f342687d3fbbb1234eb upstream.
+
+I got the following lockdep splat while testing:
+
+  ======================================================
+  WARNING: possible circular locking dependency detected
+  5.8.0-rc7-00172-g021118712e59 #932 Not tainted
+  ------------------------------------------------------
+  btrfs/229626 is trying to acquire lock:
+  ffffffff828513f0 (cpu_hotplug_lock){++++}-{0:0}, at: alloc_workqueue+0x378/0x450
+
+  but task is already holding lock:
+  ffff889dd3889518 (&fs_info->scrub_lock){+.+.}-{3:3}, at: btrfs_scrub_dev+0x11c/0x630
+
+  which lock already depends on the new lock.
+
+  the existing dependency chain (in reverse order) is:
+
+  -> #7 (&fs_info->scrub_lock){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        btrfs_scrub_dev+0x11c/0x630
+        btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+        btrfs_ioctl+0x2799/0x30a0
+        ksys_ioctl+0x83/0xc0
+        __x64_sys_ioctl+0x16/0x20
+        do_syscall_64+0x50/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  -> #6 (&fs_devs->device_list_mutex){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        btrfs_run_dev_stats+0x49/0x480
+        commit_cowonly_roots+0xb5/0x2a0
+        btrfs_commit_transaction+0x516/0xa60
+        sync_filesystem+0x6b/0x90
+        generic_shutdown_super+0x22/0x100
+        kill_anon_super+0xe/0x30
+        btrfs_kill_super+0x12/0x20
+        deactivate_locked_super+0x29/0x60
+        cleanup_mnt+0xb8/0x140
+        task_work_run+0x6d/0xb0
+        __prepare_exit_to_usermode+0x1cc/0x1e0
+        do_syscall_64+0x5c/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  -> #5 (&fs_info->tree_log_mutex){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        btrfs_commit_transaction+0x4bb/0xa60
+        sync_filesystem+0x6b/0x90
+        generic_shutdown_super+0x22/0x100
+        kill_anon_super+0xe/0x30
+        btrfs_kill_super+0x12/0x20
+        deactivate_locked_super+0x29/0x60
+        cleanup_mnt+0xb8/0x140
+        task_work_run+0x6d/0xb0
+        __prepare_exit_to_usermode+0x1cc/0x1e0
+        do_syscall_64+0x5c/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  -> #4 (&fs_info->reloc_mutex){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        btrfs_record_root_in_trans+0x43/0x70
+        start_transaction+0xd1/0x5d0
+        btrfs_dirty_inode+0x42/0xd0
+        touch_atime+0xa1/0xd0
+        btrfs_file_mmap+0x3f/0x60
+        mmap_region+0x3a4/0x640
+        do_mmap+0x376/0x580
+        vm_mmap_pgoff+0xd5/0x120
+        ksys_mmap_pgoff+0x193/0x230
+        do_syscall_64+0x50/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  -> #3 (&mm->mmap_lock#2){++++}-{3:3}:
+        __might_fault+0x68/0x90
+        _copy_to_user+0x1e/0x80
+        perf_read+0x141/0x2c0
+        vfs_read+0xad/0x1b0
+        ksys_read+0x5f/0xe0
+        do_syscall_64+0x50/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  -> #2 (&cpuctx_mutex){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        perf_event_init_cpu+0x88/0x150
+        perf_event_init+0x1db/0x20b
+        start_kernel+0x3ae/0x53c
+        secondary_startup_64+0xa4/0xb0
+
+  -> #1 (pmus_lock){+.+.}-{3:3}:
+        __mutex_lock+0x9f/0x930
+        perf_event_init_cpu+0x4f/0x150
+        cpuhp_invoke_callback+0xb1/0x900
+        _cpu_up.constprop.26+0x9f/0x130
+        cpu_up+0x7b/0xc0
+        bringup_nonboot_cpus+0x4f/0x60
+        smp_init+0x26/0x71
+        kernel_init_freeable+0x110/0x258
+        kernel_init+0xa/0x103
+        ret_from_fork+0x1f/0x30
+
+  -> #0 (cpu_hotplug_lock){++++}-{0:0}:
+        __lock_acquire+0x1272/0x2310
+        lock_acquire+0x9e/0x360
+        cpus_read_lock+0x39/0xb0
+        alloc_workqueue+0x378/0x450
+        __btrfs_alloc_workqueue+0x15d/0x200
+        btrfs_alloc_workqueue+0x51/0x160
+        scrub_workers_get+0x5a/0x170
+        btrfs_scrub_dev+0x18c/0x630
+        btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+        btrfs_ioctl+0x2799/0x30a0
+        ksys_ioctl+0x83/0xc0
+        __x64_sys_ioctl+0x16/0x20
+        do_syscall_64+0x50/0x90
+        entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  other info that might help us debug this:
+
+  Chain exists of:
+    cpu_hotplug_lock --> &fs_devs->device_list_mutex --> &fs_info->scrub_lock
+
+   Possible unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+    lock(&fs_info->scrub_lock);
+                                lock(&fs_devs->device_list_mutex);
+                                lock(&fs_info->scrub_lock);
+    lock(cpu_hotplug_lock);
+
+   *** DEADLOCK ***
+
+  2 locks held by btrfs/229626:
+   #0: ffff88bfe8bb86e0 (&fs_devs->device_list_mutex){+.+.}-{3:3}, at: btrfs_scrub_dev+0xbd/0x630
+   #1: ffff889dd3889518 (&fs_info->scrub_lock){+.+.}-{3:3}, at: btrfs_scrub_dev+0x11c/0x630
+
+  stack backtrace:
+  CPU: 15 PID: 229626 Comm: btrfs Kdump: loaded Not tainted 5.8.0-rc7-00172-g021118712e59 #932
+  Hardware name: Quanta Tioga Pass Single Side 01-0030993006/Tioga Pass Single Side, BIOS F08_3A18 12/20/2018
+  Call Trace:
+   dump_stack+0x78/0xa0
+   check_noncircular+0x165/0x180
+   __lock_acquire+0x1272/0x2310
+   lock_acquire+0x9e/0x360
+   ? alloc_workqueue+0x378/0x450
+   cpus_read_lock+0x39/0xb0
+   ? alloc_workqueue+0x378/0x450
+   alloc_workqueue+0x378/0x450
+   ? rcu_read_lock_sched_held+0x52/0x80
+   __btrfs_alloc_workqueue+0x15d/0x200
+   btrfs_alloc_workqueue+0x51/0x160
+   scrub_workers_get+0x5a/0x170
+   btrfs_scrub_dev+0x18c/0x630
+   ? start_transaction+0xd1/0x5d0
+   btrfs_dev_replace_by_ioctl.cold.21+0x10a/0x1d4
+   btrfs_ioctl+0x2799/0x30a0
+   ? do_sigaction+0x102/0x250
+   ? lockdep_hardirqs_on_prepare+0xca/0x160
+   ? _raw_spin_unlock_irq+0x24/0x30
+   ? trace_hardirqs_on+0x1c/0xe0
+   ? _raw_spin_unlock_irq+0x24/0x30
+   ? do_sigaction+0x102/0x250
+   ? ksys_ioctl+0x83/0xc0
+   ksys_ioctl+0x83/0xc0
+   __x64_sys_ioctl+0x16/0x20
+   do_syscall_64+0x50/0x90
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+This happens because we're allocating the scrub workqueues under the
+scrub and device list mutex, which brings in a whole host of other
+dependencies.
+
+Because the work queue allocation is done with GFP_KERNEL, it can
+trigger reclaim, which can lead to a transaction commit, which in turns
+needs the device_list_mutex, it can lead to a deadlock. A different
+problem for which this fix is a solution.
+
+Fix this by moving the actual allocation outside of the
+scrub lock, and then only take the lock once we're ready to actually
+assign them to the fs_info.  We'll now have to cleanup the workqueues in
+a few more places, so I've added a helper to do the refcount dance to
+safely free the workqueues.
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.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/scrub.c |  122 +++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 70 insertions(+), 52 deletions(-)
+
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3742,50 +3742,84 @@ static noinline_for_stack int scrub_supe
+       return 0;
+ }
++static void scrub_workers_put(struct btrfs_fs_info *fs_info)
++{
++      if (refcount_dec_and_mutex_lock(&fs_info->scrub_workers_refcnt,
++                                      &fs_info->scrub_lock)) {
++              struct btrfs_workqueue *scrub_workers = NULL;
++              struct btrfs_workqueue *scrub_wr_comp = NULL;
++              struct btrfs_workqueue *scrub_parity = NULL;
++
++              scrub_workers = fs_info->scrub_workers;
++              scrub_wr_comp = fs_info->scrub_wr_completion_workers;
++              scrub_parity = fs_info->scrub_parity_workers;
++
++              fs_info->scrub_workers = NULL;
++              fs_info->scrub_wr_completion_workers = NULL;
++              fs_info->scrub_parity_workers = NULL;
++              mutex_unlock(&fs_info->scrub_lock);
++
++              btrfs_destroy_workqueue(scrub_workers);
++              btrfs_destroy_workqueue(scrub_wr_comp);
++              btrfs_destroy_workqueue(scrub_parity);
++      }
++}
++
+ /*
+  * get a reference count on fs_info->scrub_workers. start worker if necessary
+  */
+ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
+                                               int is_dev_replace)
+ {
++      struct btrfs_workqueue *scrub_workers = NULL;
++      struct btrfs_workqueue *scrub_wr_comp = NULL;
++      struct btrfs_workqueue *scrub_parity = NULL;
+       unsigned int flags = WQ_FREEZABLE | WQ_UNBOUND;
+       int max_active = fs_info->thread_pool_size;
++      int ret = -ENOMEM;
+-      lockdep_assert_held(&fs_info->scrub_lock);
++      if (refcount_inc_not_zero(&fs_info->scrub_workers_refcnt))
++              return 0;
+-      if (refcount_read(&fs_info->scrub_workers_refcnt) == 0) {
+-              ASSERT(fs_info->scrub_workers == NULL);
+-              fs_info->scrub_workers = btrfs_alloc_workqueue(fs_info, "scrub",
+-                              flags, is_dev_replace ? 1 : max_active, 4);
+-              if (!fs_info->scrub_workers)
+-                      goto fail_scrub_workers;
+-
+-              ASSERT(fs_info->scrub_wr_completion_workers == NULL);
+-              fs_info->scrub_wr_completion_workers =
+-                      btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
+-                                            max_active, 2);
+-              if (!fs_info->scrub_wr_completion_workers)
+-                      goto fail_scrub_wr_completion_workers;
++      scrub_workers = btrfs_alloc_workqueue(fs_info, "scrub", flags,
++                                            is_dev_replace ? 1 : max_active, 4);
++      if (!scrub_workers)
++              goto fail_scrub_workers;
+-              ASSERT(fs_info->scrub_parity_workers == NULL);
+-              fs_info->scrub_parity_workers =
+-                      btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
++      scrub_wr_comp = btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
+                                             max_active, 2);
+-              if (!fs_info->scrub_parity_workers)
+-                      goto fail_scrub_parity_workers;
++      if (!scrub_wr_comp)
++              goto fail_scrub_wr_completion_workers;
++      scrub_parity = btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
++                                           max_active, 2);
++      if (!scrub_parity)
++              goto fail_scrub_parity_workers;
++
++      mutex_lock(&fs_info->scrub_lock);
++      if (refcount_read(&fs_info->scrub_workers_refcnt) == 0) {
++              ASSERT(fs_info->scrub_workers == NULL &&
++                     fs_info->scrub_wr_completion_workers == NULL &&
++                     fs_info->scrub_parity_workers == NULL);
++              fs_info->scrub_workers = scrub_workers;
++              fs_info->scrub_wr_completion_workers = scrub_wr_comp;
++              fs_info->scrub_parity_workers = scrub_parity;
+               refcount_set(&fs_info->scrub_workers_refcnt, 1);
+-      } else {
+-              refcount_inc(&fs_info->scrub_workers_refcnt);
++              mutex_unlock(&fs_info->scrub_lock);
++              return 0;
+       }
+-      return 0;
++      /* Other thread raced in and created the workers for us */
++      refcount_inc(&fs_info->scrub_workers_refcnt);
++      mutex_unlock(&fs_info->scrub_lock);
++      ret = 0;
++      btrfs_destroy_workqueue(scrub_parity);
+ fail_scrub_parity_workers:
+-      btrfs_destroy_workqueue(fs_info->scrub_wr_completion_workers);
++      btrfs_destroy_workqueue(scrub_wr_comp);
+ fail_scrub_wr_completion_workers:
+-      btrfs_destroy_workqueue(fs_info->scrub_workers);
++      btrfs_destroy_workqueue(scrub_workers);
+ fail_scrub_workers:
+-      return -ENOMEM;
++      return ret;
+ }
+ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+@@ -3796,9 +3830,6 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+       int ret;
+       struct btrfs_device *dev;
+       unsigned int nofs_flag;
+-      struct btrfs_workqueue *scrub_workers = NULL;
+-      struct btrfs_workqueue *scrub_wr_comp = NULL;
+-      struct btrfs_workqueue *scrub_parity = NULL;
+       if (btrfs_fs_closing(fs_info))
+               return -EAGAIN;
+@@ -3845,13 +3876,17 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+       if (IS_ERR(sctx))
+               return PTR_ERR(sctx);
++      ret = scrub_workers_get(fs_info, is_dev_replace);
++      if (ret)
++              goto out_free_ctx;
++
+       mutex_lock(&fs_info->fs_devices->device_list_mutex);
+       dev = btrfs_find_device(fs_info->fs_devices, devid, NULL, NULL, true);
+       if (!dev || (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) &&
+                    !is_dev_replace)) {
+               mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+               ret = -ENODEV;
+-              goto out_free_ctx;
++              goto out;
+       }
+       if (!is_dev_replace && !readonly &&
+@@ -3860,7 +3895,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+               btrfs_err_in_rcu(fs_info, "scrub: device %s is not writable",
+                               rcu_str_deref(dev->name));
+               ret = -EROFS;
+-              goto out_free_ctx;
++              goto out;
+       }
+       mutex_lock(&fs_info->scrub_lock);
+@@ -3869,7 +3904,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+               mutex_unlock(&fs_info->scrub_lock);
+               mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+               ret = -EIO;
+-              goto out_free_ctx;
++              goto out;
+       }
+       down_read(&fs_info->dev_replace.rwsem);
+@@ -3880,17 +3915,10 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+               mutex_unlock(&fs_info->scrub_lock);
+               mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+               ret = -EINPROGRESS;
+-              goto out_free_ctx;
++              goto out;
+       }
+       up_read(&fs_info->dev_replace.rwsem);
+-      ret = scrub_workers_get(fs_info, is_dev_replace);
+-      if (ret) {
+-              mutex_unlock(&fs_info->scrub_lock);
+-              mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+-              goto out_free_ctx;
+-      }
+-
+       sctx->readonly = readonly;
+       dev->scrub_ctx = sctx;
+       mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+@@ -3943,24 +3971,14 @@ int btrfs_scrub_dev(struct btrfs_fs_info
+       mutex_lock(&fs_info->scrub_lock);
+       dev->scrub_ctx = NULL;
+-      if (refcount_dec_and_test(&fs_info->scrub_workers_refcnt)) {
+-              scrub_workers = fs_info->scrub_workers;
+-              scrub_wr_comp = fs_info->scrub_wr_completion_workers;
+-              scrub_parity = fs_info->scrub_parity_workers;
+-
+-              fs_info->scrub_workers = NULL;
+-              fs_info->scrub_wr_completion_workers = NULL;
+-              fs_info->scrub_parity_workers = NULL;
+-      }
+       mutex_unlock(&fs_info->scrub_lock);
+-      btrfs_destroy_workqueue(scrub_workers);
+-      btrfs_destroy_workqueue(scrub_wr_comp);
+-      btrfs_destroy_workqueue(scrub_parity);
++      scrub_workers_put(fs_info);
+       scrub_put_ctx(sctx);
+       return ret;
+-
++out:
++      scrub_workers_put(fs_info);
+ out_free_ctx:
+       scrub_free_ctx(sctx);
diff --git a/queue-5.4/btrfs-drop-path-before-adding-new-uuid-tree-entry.patch b/queue-5.4/btrfs-drop-path-before-adding-new-uuid-tree-entry.patch
new file mode 100644 (file)
index 0000000..6fefbd6
--- /dev/null
@@ -0,0 +1,145 @@
+From 9771a5cf937129307d9f58922d60484d58ababe7 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:26 -0400
+Subject: btrfs: drop path before adding new uuid tree entry
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 9771a5cf937129307d9f58922d60484d58ababe7 upstream.
+
+With the conversion of the tree locks to rwsem I got the following
+lockdep splat:
+
+  ======================================================
+  WARNING: possible circular locking dependency detected
+  5.8.0-rc7-00167-g0d7ba0c5b375-dirty #925 Not tainted
+  ------------------------------------------------------
+  btrfs-uuid/7955 is trying to acquire lock:
+  ffff88bfbafec0f8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+  but task is already holding lock:
+  ffff88bfbafef2a8 (btrfs-uuid-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+  which lock already depends on the new lock.
+
+  the existing dependency chain (in reverse order) is:
+
+  -> #1 (btrfs-uuid-00){++++}-{3:3}:
+        down_read_nested+0x3e/0x140
+        __btrfs_tree_read_lock+0x39/0x180
+        __btrfs_read_lock_root_node+0x3a/0x50
+        btrfs_search_slot+0x4bd/0x990
+        btrfs_uuid_tree_add+0x89/0x2d0
+        btrfs_uuid_scan_kthread+0x330/0x390
+        kthread+0x133/0x150
+        ret_from_fork+0x1f/0x30
+
+  -> #0 (btrfs-root-00){++++}-{3:3}:
+        __lock_acquire+0x1272/0x2310
+        lock_acquire+0x9e/0x360
+        down_read_nested+0x3e/0x140
+        __btrfs_tree_read_lock+0x39/0x180
+        __btrfs_read_lock_root_node+0x3a/0x50
+        btrfs_search_slot+0x4bd/0x990
+        btrfs_find_root+0x45/0x1b0
+        btrfs_read_tree_root+0x61/0x100
+        btrfs_get_root_ref.part.50+0x143/0x630
+        btrfs_uuid_tree_iterate+0x207/0x314
+        btrfs_uuid_rescan_kthread+0x12/0x50
+        kthread+0x133/0x150
+        ret_from_fork+0x1f/0x30
+
+  other info that might help us debug this:
+
+   Possible unsafe locking scenario:
+
+        CPU0                    CPU1
+        ----                    ----
+    lock(btrfs-uuid-00);
+                                lock(btrfs-root-00);
+                                lock(btrfs-uuid-00);
+    lock(btrfs-root-00);
+
+   *** DEADLOCK ***
+
+  1 lock held by btrfs-uuid/7955:
+   #0: ffff88bfbafef2a8 (btrfs-uuid-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x39/0x180
+
+  stack backtrace:
+  CPU: 73 PID: 7955 Comm: btrfs-uuid Kdump: loaded Not tainted 5.8.0-rc7-00167-g0d7ba0c5b375-dirty #925
+  Hardware name: Quanta Tioga Pass Single Side 01-0030993006/Tioga Pass Single Side, BIOS F08_3A18 12/20/2018
+  Call Trace:
+   dump_stack+0x78/0xa0
+   check_noncircular+0x165/0x180
+   __lock_acquire+0x1272/0x2310
+   lock_acquire+0x9e/0x360
+   ? __btrfs_tree_read_lock+0x39/0x180
+   ? btrfs_root_node+0x1c/0x1d0
+   down_read_nested+0x3e/0x140
+   ? __btrfs_tree_read_lock+0x39/0x180
+   __btrfs_tree_read_lock+0x39/0x180
+   __btrfs_read_lock_root_node+0x3a/0x50
+   btrfs_search_slot+0x4bd/0x990
+   btrfs_find_root+0x45/0x1b0
+   btrfs_read_tree_root+0x61/0x100
+   btrfs_get_root_ref.part.50+0x143/0x630
+   btrfs_uuid_tree_iterate+0x207/0x314
+   ? btree_readpage+0x20/0x20
+   btrfs_uuid_rescan_kthread+0x12/0x50
+   kthread+0x133/0x150
+   ? kthread_create_on_node+0x60/0x60
+   ret_from_fork+0x1f/0x30
+
+This problem exists because we have two different rescan threads,
+btrfs_uuid_scan_kthread which creates the uuid tree, and
+btrfs_uuid_tree_iterate that goes through and updates or deletes any out
+of date roots.  The problem is they both do things in different order.
+btrfs_uuid_scan_kthread() reads the tree_root, and then inserts entries
+into the uuid_root.  btrfs_uuid_tree_iterate() scans the uuid_root, but
+then does a btrfs_get_fs_root() which can read from the tree_root.
+
+It's actually easy enough to not be holding the path in
+btrfs_uuid_scan_kthread() when we add a uuid entry, as we already drop
+it further down and re-start the search when we loop.  So simply move
+the path release before we add our entry to the uuid tree.
+
+This also fixes a problem where we're holding a path open after we do
+btrfs_end_transaction(), which has it's own problems.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.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/volumes.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -4568,6 +4568,7 @@ static int btrfs_uuid_scan_kthread(void
+                       goto skip;
+               }
+ update_tree:
++              btrfs_release_path(path);
+               if (!btrfs_is_empty_uuid(root_item.uuid)) {
+                       ret = btrfs_uuid_tree_add(trans, root_item.uuid,
+                                                 BTRFS_UUID_KEY_SUBVOL,
+@@ -4592,6 +4593,7 @@ update_tree:
+               }
+ skip:
++              btrfs_release_path(path);
+               if (trans) {
+                       ret = btrfs_end_transaction(trans);
+                       trans = NULL;
+@@ -4599,7 +4601,6 @@ skip:
+                               break;
+               }
+-              btrfs_release_path(path);
+               if (key.offset < (u64)-1) {
+                       key.offset++;
+               } else if (key.type < BTRFS_ROOT_ITEM_KEY) {
diff --git a/queue-5.4/btrfs-set-the-correct-lockdep-class-for-new-nodes.patch b/queue-5.4/btrfs-set-the-correct-lockdep-class-for-new-nodes.patch
new file mode 100644 (file)
index 0000000..299c843
--- /dev/null
@@ -0,0 +1,43 @@
+From ad24466588ab7d7c879053c5afd919b0c555fec0 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:30 -0400
+Subject: btrfs: set the correct lockdep class for new nodes
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit ad24466588ab7d7c879053c5afd919b0c555fec0 upstream.
+
+When flipping over to the rw_semaphore I noticed I'd get a lockdep splat
+in replace_path(), which is weird because we're swapping the reloc root
+with the actual target root.  Turns out this is because we're using the
+root->root_key.objectid as the root id for the newly allocated tree
+block when setting the lockdep class, however we need to be using the
+actual owner of this new block, which is saved in owner.
+
+The affected path is through btrfs_copy_root as all other callers of
+btrfs_alloc_tree_block (which calls init_new_buffer) have root_objectid
+== root->root_key.objectid .
+
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.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/extent-tree.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4446,7 +4446,7 @@ btrfs_init_new_buffer(struct btrfs_trans
+               return ERR_PTR(-EUCLEAN);
+       }
+-      btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level);
++      btrfs_set_buffer_lockdep_class(owner, buf, level);
+       btrfs_tree_lock(buf);
+       btrfs_clean_tree_block(buf);
+       clear_bit(EXTENT_BUFFER_STALE, &buf->bflags);
diff --git a/queue-5.4/btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch b/queue-5.4/btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch
new file mode 100644 (file)
index 0000000..d485064
--- /dev/null
@@ -0,0 +1,55 @@
+From d3beaa253fd6fa40b8b18a216398e6e5376a9d21 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 10 Aug 2020 11:42:31 -0400
+Subject: btrfs: set the lockdep class for log tree extent buffers
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit d3beaa253fd6fa40b8b18a216398e6e5376a9d21 upstream.
+
+These are special extent buffers that get rewound in order to lookup
+the state of the tree at a specific point in time.  As such they do not
+go through the normal initialization paths that set their lockdep class,
+so handle them appropriately when they are created and before they are
+locked.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.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/ctree.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1339,6 +1339,8 @@ tree_mod_log_rewind(struct btrfs_fs_info
+       btrfs_tree_read_unlock_blocking(eb);
+       free_extent_buffer(eb);
++      btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb_rewin),
++                                     eb_rewin, btrfs_header_level(eb_rewin));
+       btrfs_tree_read_lock(eb_rewin);
+       __tree_mod_log_rewind(fs_info, eb_rewin, time_seq, tm);
+       WARN_ON(btrfs_header_nritems(eb_rewin) >
+@@ -1412,7 +1414,6 @@ get_old_root(struct btrfs_root *root, u6
+       if (!eb)
+               return NULL;
+-      btrfs_tree_read_lock(eb);
+       if (old_root) {
+               btrfs_set_header_bytenr(eb, eb->start);
+               btrfs_set_header_backref_rev(eb, BTRFS_MIXED_BACKREF_REV);
+@@ -1420,6 +1421,9 @@ get_old_root(struct btrfs_root *root, u6
+               btrfs_set_header_level(eb, old_root->level);
+               btrfs_set_header_generation(eb, old_generation);
+       }
++      btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb), eb,
++                                     btrfs_header_level(eb));
++      btrfs_tree_read_lock(eb);
+       if (tm)
+               __tree_mod_log_rewind(fs_info, eb, time_seq, tm);
+       else
diff --git a/queue-5.4/btrfs-tree-checker-fix-the-error-message-for-transid-error.patch b/queue-5.4/btrfs-tree-checker-fix-the-error-message-for-transid-error.patch
new file mode 100644 (file)
index 0000000..bbca7a1
--- /dev/null
@@ -0,0 +1,35 @@
+From f96d6960abbc52e26ad124e69e6815283d3e1674 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Tue, 25 Aug 2020 21:42:51 +0800
+Subject: btrfs: tree-checker: fix the error message for transid error
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit f96d6960abbc52e26ad124e69e6815283d3e1674 upstream.
+
+The error message for inode transid is the same as for inode generation,
+which makes us unable to detect the real problem.
+
+Reported-by: Tyler Richmond <t.d.richmond@gmail.com>
+Fixes: 496245cac57e ("btrfs: tree-checker: Verify inode item")
+CC: stable@vger.kernel.org # 5.4+
+Reviewed-by: Marcos Paulo de Souza <mpdesouza@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-checker.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -772,7 +772,7 @@ static int check_inode_item(struct exten
+       /* Here we use super block generation + 1 to handle log tree */
+       if (btrfs_inode_generation(leaf, iitem) > super_gen + 1) {
+               inode_item_err(fs_info, leaf, slot,
+-                      "invalid inode generation: has %llu expect (0, %llu]",
++                      "invalid inode transid: has %llu expect [0, %llu]",
+                              btrfs_inode_generation(leaf, iitem),
+                              super_gen + 1);
+               return -EUCLEAN;
diff --git a/queue-5.4/ext2-don-t-update-mtime-on-cow-faults.patch b/queue-5.4/ext2-don-t-update-mtime-on-cow-faults.patch
new file mode 100644 (file)
index 0000000..528a66b
--- /dev/null
@@ -0,0 +1,61 @@
+From 1ef6ea0efe8e68d0299dad44c39dc6ad9e5d1f39 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sat, 5 Sep 2020 08:12:01 -0400
+Subject: ext2: don't update mtime on COW faults
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 1ef6ea0efe8e68d0299dad44c39dc6ad9e5d1f39 upstream.
+
+When running in a dax mode, if the user maps a page with MAP_PRIVATE and
+PROT_WRITE, the ext2 filesystem would incorrectly update ctime and mtime
+when the user hits a COW fault.
+
+This breaks building of the Linux kernel.  How to reproduce:
+
+ 1. extract the Linux kernel tree on dax-mounted ext2 filesystem
+ 2. run make clean
+ 3. run make -j12
+ 4. run make -j12
+
+at step 4, make would incorrectly rebuild the whole kernel (although it
+was already built in step 3).
+
+The reason for the breakage is that almost all object files depend on
+objtool.  When we run objtool, it takes COW page fault on its .data
+section, and these faults will incorrectly update the timestamp of the
+objtool binary.  The updated timestamp causes make to rebuild the whole
+tree.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext2/file.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext2/file.c
++++ b/fs/ext2/file.c
+@@ -93,8 +93,10 @@ static vm_fault_t ext2_dax_fault(struct
+       struct inode *inode = file_inode(vmf->vma->vm_file);
+       struct ext2_inode_info *ei = EXT2_I(inode);
+       vm_fault_t ret;
++      bool write = (vmf->flags & FAULT_FLAG_WRITE) &&
++              (vmf->vma->vm_flags & VM_SHARED);
+-      if (vmf->flags & FAULT_FLAG_WRITE) {
++      if (write) {
+               sb_start_pagefault(inode->i_sb);
+               file_update_time(vmf->vma->vm_file);
+       }
+@@ -103,7 +105,7 @@ static vm_fault_t ext2_dax_fault(struct
+       ret = dax_iomap_fault(vmf, PE_SIZE_PTE, NULL, NULL, &ext2_iomap_ops);
+       up_read(&ei->dax_sem);
+-      if (vmf->flags & FAULT_FLAG_WRITE)
++      if (write)
+               sb_end_pagefault(inode->i_sb);
+       return ret;
+ }
diff --git a/queue-5.4/iommu-vt-d-handle-36bit-addressing-for-x86-32.patch b/queue-5.4/iommu-vt-d-handle-36bit-addressing-for-x86-32.patch
new file mode 100644 (file)
index 0000000..4b12d2a
--- /dev/null
@@ -0,0 +1,74 @@
+From 29aaebbca4abc4cceb38738483051abefafb6950 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris@chris-wilson.co.uk>
+Date: Sat, 22 Aug 2020 17:02:09 +0100
+Subject: iommu/vt-d: Handle 36bit addressing for x86-32
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+commit 29aaebbca4abc4cceb38738483051abefafb6950 upstream.
+
+Beware that the address size for x86-32 may exceed unsigned long.
+
+[    0.368971] UBSAN: shift-out-of-bounds in drivers/iommu/intel/iommu.c:128:14
+[    0.369055] shift exponent 36 is too large for 32-bit type 'long unsigned int'
+
+If we don't handle the wide addresses, the pages are mismapped and the
+device read/writes go astray, detected as DMAR faults and leading to
+device failure. The behaviour changed (from working to broken) in commit
+fa954e683178 ("iommu/vt-d: Delegate the dma domain to upper layer"), but
+the error looks older.
+
+Fixes: fa954e683178 ("iommu/vt-d: Delegate the dma domain to upper layer")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Acked-by: Lu Baolu <baolu.lu@linux.intel.com>
+Cc: James Sewart <jamessewart@arista.com>
+Cc: Lu Baolu <baolu.lu@linux.intel.com>
+Cc: Joerg Roedel <jroedel@suse.de>
+Cc: <stable@vger.kernel.org> # v5.3+
+Link: https://lore.kernel.org/r/20200822160209.28512-1-chris@chris-wilson.co.uk
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -123,29 +123,29 @@ static inline unsigned int level_to_offs
+       return (level - 1) * LEVEL_STRIDE;
+ }
+-static inline int pfn_level_offset(unsigned long pfn, int level)
++static inline int pfn_level_offset(u64 pfn, int level)
+ {
+       return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK;
+ }
+-static inline unsigned long level_mask(int level)
++static inline u64 level_mask(int level)
+ {
+-      return -1UL << level_to_offset_bits(level);
++      return -1ULL << level_to_offset_bits(level);
+ }
+-static inline unsigned long level_size(int level)
++static inline u64 level_size(int level)
+ {
+-      return 1UL << level_to_offset_bits(level);
++      return 1ULL << level_to_offset_bits(level);
+ }
+-static inline unsigned long align_to_level(unsigned long pfn, int level)
++static inline u64 align_to_level(u64 pfn, int level)
+ {
+       return (pfn + level_size(level) - 1) & level_mask(level);
+ }
+ static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
+ {
+-      return  1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
++      return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH);
+ }
+ /* VT-d pages must always be _smaller_ than MM pages. Otherwise things
index e11341e118976b68ed074740039630760c721e62..565f32b38ec41b7ea51cee35bdac113f3e5c0a0b 100644 (file)
@@ -73,3 +73,13 @@ include-linux-log2.h-add-missing-around-n-in-roundup.patch
 vfio-type1-support-faulting-pfnmap-vmas.patch
 vfio-pci-fault-mmaps-to-enable-vma-tracking.patch
 vfio-pci-invalidate-mmaps-and-block-mmio-access-on-d.patch
+iommu-vt-d-handle-36bit-addressing-for-x86-32.patch
+tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch
+ext2-don-t-update-mtime-on-cow-faults.patch
+xfs-don-t-update-mtime-on-cow-faults.patch
+arc-perf-don-t-bail-setup-if-pct-irq-missing-in-device-tree.patch
+btrfs-drop-path-before-adding-new-uuid-tree-entry.patch
+btrfs-allocate-scrub-workqueues-outside-of-locks.patch
+btrfs-set-the-correct-lockdep-class-for-new-nodes.patch
+btrfs-set-the-lockdep-class-for-log-tree-extent-buffers.patch
+btrfs-tree-checker-fix-the-error-message-for-transid-error.patch
diff --git a/queue-5.4/tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch b/queue-5.4/tracing-kprobes-x86-ptrace-fix-regs-argument-order-for-i386.patch
new file mode 100644 (file)
index 0000000..7fbbbf2
--- /dev/null
@@ -0,0 +1,43 @@
+From 2356bb4b8221d7dc8c7beb810418122ed90254c9 Mon Sep 17 00:00:00 2001
+From: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+Date: Fri, 28 Aug 2020 17:02:46 +0530
+Subject: tracing/kprobes, x86/ptrace: Fix regs argument order for i386
+
+From: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+
+commit 2356bb4b8221d7dc8c7beb810418122ed90254c9 upstream.
+
+On i386, the order of parameters passed on regs is eax,edx,and ecx
+(as per regparm(3) calling conventions).
+
+Change the mapping in regs_get_kernel_argument(), so that arg1=ax
+arg2=dx, and arg3=cx.
+
+Running the selftests testcase kprobes_args_use.tc shows the result
+as passed.
+
+Fixes: 3c88ee194c28 ("x86: ptrace: Add function argument access API")
+Signed-off-by: Vamshi K Sthambamkadi <vamshi.k.sthambamkadi@gmail.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: <stable@vger.kernel.org>
+Link: https://lkml.kernel.org/r/20200828113242.GA1424@cosmos
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/ptrace.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -309,8 +309,8 @@ static inline unsigned long regs_get_ker
+       static const unsigned int argument_offs[] = {
+ #ifdef __i386__
+               offsetof(struct pt_regs, ax),
+-              offsetof(struct pt_regs, cx),
+               offsetof(struct pt_regs, dx),
++              offsetof(struct pt_regs, cx),
+ #define NR_REG_ARGUMENTS 3
+ #else
+               offsetof(struct pt_regs, di),
diff --git a/queue-5.4/xfs-don-t-update-mtime-on-cow-faults.patch b/queue-5.4/xfs-don-t-update-mtime-on-cow-faults.patch
new file mode 100644 (file)
index 0000000..dce1067
--- /dev/null
@@ -0,0 +1,73 @@
+From b17164e258e3888d376a7434415013175d637377 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sat, 5 Sep 2020 08:13:02 -0400
+Subject: xfs: don't update mtime on COW faults
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit b17164e258e3888d376a7434415013175d637377 upstream.
+
+When running in a dax mode, if the user maps a page with MAP_PRIVATE and
+PROT_WRITE, the xfs filesystem would incorrectly update ctime and mtime
+when the user hits a COW fault.
+
+This breaks building of the Linux kernel.  How to reproduce:
+
+ 1. extract the Linux kernel tree on dax-mounted xfs filesystem
+ 2. run make clean
+ 3. run make -j12
+ 4. run make -j12
+
+at step 4, make would incorrectly rebuild the whole kernel (although it
+was already built in step 3).
+
+The reason for the breakage is that almost all object files depend on
+objtool.  When we run objtool, it takes COW page fault on its .data
+section, and these faults will incorrectly update the timestamp of the
+objtool binary.  The updated timestamp causes make to rebuild the whole
+tree.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_file.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_file.c
++++ b/fs/xfs/xfs_file.c
+@@ -1172,6 +1172,14 @@ __xfs_filemap_fault(
+       return ret;
+ }
++static inline bool
++xfs_is_write_fault(
++      struct vm_fault         *vmf)
++{
++      return (vmf->flags & FAULT_FLAG_WRITE) &&
++             (vmf->vma->vm_flags & VM_SHARED);
++}
++
+ static vm_fault_t
+ xfs_filemap_fault(
+       struct vm_fault         *vmf)
+@@ -1179,7 +1187,7 @@ xfs_filemap_fault(
+       /* DAX can shortcut the normal fault path on write faults! */
+       return __xfs_filemap_fault(vmf, PE_SIZE_PTE,
+                       IS_DAX(file_inode(vmf->vma->vm_file)) &&
+-                      (vmf->flags & FAULT_FLAG_WRITE));
++                      xfs_is_write_fault(vmf));
+ }
+ static vm_fault_t
+@@ -1192,7 +1200,7 @@ xfs_filemap_huge_fault(
+       /* DAX can shortcut the normal fault path on write faults! */
+       return __xfs_filemap_fault(vmf, pe_size,
+-                      (vmf->flags & FAULT_FLAG_WRITE));
++                      xfs_is_write_fault(vmf));
+ }
+ static vm_fault_t