--- /dev/null
+From 969f5ea627570e91c9d54403287ee3ed657f58fe Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Mon, 29 Apr 2019 13:03:57 +0100
+Subject: arm64: errata: Add workaround for Cortex-A76 erratum #1463225
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit 969f5ea627570e91c9d54403287ee3ed657f58fe upstream.
+
+Revisions of the Cortex-A76 CPU prior to r4p0 are affected by an erratum
+that can prevent interrupts from being taken when single-stepping.
+
+This patch implements a software workaround to prevent userspace from
+effectively being able to disable interrupts.
+
+Cc: <stable@vger.kernel.org>
+Cc: Marc Zyngier <marc.zyngier@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ Documentation/arm64/silicon-errata.txt | 1
+ arch/arm64/Kconfig | 18 ++++++++++++++++
+ arch/arm64/include/asm/cpucaps.h | 3 +-
+ arch/arm64/include/asm/cputype.h | 2 +
+ arch/arm64/kernel/cpu_errata.c | 24 +++++++++++++++++++++
+ arch/arm64/kernel/syscall.c | 31 +++++++++++++++++++++++++++
+ arch/arm64/mm/fault.c | 37 +++++++++++++++++++++++++++++++--
+ 7 files changed, 113 insertions(+), 3 deletions(-)
+
+--- a/Documentation/arm64/silicon-errata.txt
++++ b/Documentation/arm64/silicon-errata.txt
+@@ -58,6 +58,7 @@ stable kernels.
+ | ARM | Cortex-A72 | #853709 | N/A |
+ | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
+ | ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
++| ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 |
+ | ARM | MMU-500 | #841119,#826419 | N/A |
+ | | | | |
+ | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -479,6 +479,24 @@ config ARM64_ERRATUM_1024718
+
+ If unsure, say Y.
+
++config ARM64_ERRATUM_1463225
++ bool "Cortex-A76: Software Step might prevent interrupt recognition"
++ default y
++ help
++ This option adds a workaround for Arm Cortex-A76 erratum 1463225.
++
++ On the affected Cortex-A76 cores (r0p0 to r3p1), software stepping
++ of a system call instruction (SVC) can prevent recognition of
++ subsequent interrupts when software stepping is disabled in the
++ exception handler of the system call and either kernel debugging
++ is enabled or VHE is in use.
++
++ Work around the erratum by triggering a dummy step exception
++ when handling a system call from a task that is being stepped
++ in a VHE configuration of the kernel.
++
++ If unsure, say Y.
++
+ config CAVIUM_ERRATUM_22375
+ bool "Cavium erratum 22375, 24313"
+ default y
+--- a/arch/arm64/include/asm/cpucaps.h
++++ b/arch/arm64/include/asm/cpucaps.h
+@@ -51,7 +51,8 @@
+ #define ARM64_SSBD 30
+ #define ARM64_MISMATCHED_CACHE_TYPE 31
+ #define ARM64_HAS_STAGE2_FWB 32
++#define ARM64_WORKAROUND_1463225 33
+
+-#define ARM64_NCAPS 33
++#define ARM64_NCAPS 34
+
+ #endif /* __ASM_CPUCAPS_H */
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -86,6 +86,7 @@
+ #define ARM_CPU_PART_CORTEX_A75 0xD0A
+ #define ARM_CPU_PART_CORTEX_A35 0xD04
+ #define ARM_CPU_PART_CORTEX_A55 0xD05
++#define ARM_CPU_PART_CORTEX_A76 0xD0B
+
+ #define APM_CPU_PART_POTENZA 0x000
+
+@@ -110,6 +111,7 @@
+ #define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
+ #define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
+ #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
++#define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
+ #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+ #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+ #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -411,6 +411,22 @@ static bool has_ssbd_mitigation(const st
+ }
+ #endif /* CONFIG_ARM64_SSBD */
+
++#ifdef CONFIG_ARM64_ERRATUM_1463225
++DEFINE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
++
++static bool
++has_cortex_a76_erratum_1463225(const struct arm64_cpu_capabilities *entry,
++ int scope)
++{
++ u32 midr = read_cpuid_id();
++ /* Cortex-A76 r0p0 - r3p1 */
++ struct midr_range range = MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 1);
++
++ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
++ return is_midr_in_range(midr, &range) && is_kernel_in_hyp_mode();
++}
++#endif
++
+ #define CAP_MIDR_RANGE(model, v_min, r_min, v_max, r_max) \
+ .matches = is_affected_midr_range, \
+ .midr_range = MIDR_RANGE(model, v_min, r_min, v_max, r_max)
+@@ -680,6 +696,14 @@ const struct arm64_cpu_capabilities arm6
+ .matches = has_ssbd_mitigation,
+ },
+ #endif
++#ifdef CONFIG_ARM64_ERRATUM_1463225
++ {
++ .desc = "ARM erratum 1463225",
++ .capability = ARM64_WORKAROUND_1463225,
++ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
++ .matches = has_cortex_a76_erratum_1463225,
++ },
++#endif
+ {
+ }
+ };
+--- a/arch/arm64/kernel/syscall.c
++++ b/arch/arm64/kernel/syscall.c
+@@ -8,6 +8,7 @@
+ #include <linux/syscalls.h>
+
+ #include <asm/daifflags.h>
++#include <asm/debug-monitors.h>
+ #include <asm/fpsimd.h>
+ #include <asm/syscall.h>
+ #include <asm/thread_info.h>
+@@ -60,6 +61,35 @@ static inline bool has_syscall_work(unsi
+ int syscall_trace_enter(struct pt_regs *regs);
+ void syscall_trace_exit(struct pt_regs *regs);
+
++#ifdef CONFIG_ARM64_ERRATUM_1463225
++DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
++
++static void cortex_a76_erratum_1463225_svc_handler(void)
++{
++ u32 reg, val;
++
++ if (!unlikely(test_thread_flag(TIF_SINGLESTEP)))
++ return;
++
++ if (!unlikely(this_cpu_has_cap(ARM64_WORKAROUND_1463225)))
++ return;
++
++ __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 1);
++ reg = read_sysreg(mdscr_el1);
++ val = reg | DBG_MDSCR_SS | DBG_MDSCR_KDE;
++ write_sysreg(val, mdscr_el1);
++ asm volatile("msr daifclr, #8");
++ isb();
++
++ /* We will have taken a single-step exception by this point */
++
++ write_sysreg(reg, mdscr_el1);
++ __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
++}
++#else
++static void cortex_a76_erratum_1463225_svc_handler(void) { }
++#endif /* CONFIG_ARM64_ERRATUM_1463225 */
++
+ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
+ const syscall_fn_t syscall_table[])
+ {
+@@ -68,6 +98,7 @@ static void el0_svc_common(struct pt_reg
+ regs->orig_x0 = regs->regs[0];
+ regs->syscallno = scno;
+
++ cortex_a76_erratum_1463225_svc_handler();
+ local_daif_restore(DAIF_PROCCTX);
+ user_exit();
+
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -827,14 +827,47 @@ void __init hook_debug_fault_code(int nr
+ debug_fault_info[nr].name = name;
+ }
+
++#ifdef CONFIG_ARM64_ERRATUM_1463225
++DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
++
++static int __exception
++cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
++{
++ if (user_mode(regs))
++ return 0;
++
++ if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
++ return 0;
++
++ /*
++ * We've taken a dummy step exception from the kernel to ensure
++ * that interrupts are re-enabled on the syscall path. Return back
++ * to cortex_a76_erratum_1463225_svc_handler() with debug exceptions
++ * masked so that we can safely restore the mdscr and get on with
++ * handling the syscall.
++ */
++ regs->pstate |= PSR_D_BIT;
++ return 1;
++}
++#else
++static int __exception
++cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
++{
++ return 0;
++}
++#endif /* CONFIG_ARM64_ERRATUM_1463225 */
++
+ asmlinkage int __exception do_debug_exception(unsigned long addr_if_watchpoint,
+- unsigned int esr,
+- struct pt_regs *regs)
++ unsigned int esr,
++ struct pt_regs *regs)
+ {
+ const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
+ unsigned long pc = instruction_pointer(regs);
+ int rv;
+
++ if (cortex_a76_erratum_1463225_debug_handler(regs))
++ return 0;
++
+ /*
+ * Tell lockdep we disabled irqs in entry.S. Do nothing if they were
+ * already disabled to preserve the last enabled/disabled addresses.
--- /dev/null
+From 38e3eebff643db725633657d1d87a3be019d1018 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 16 Jan 2019 11:00:57 -0500
+Subject: btrfs: honor path->skip_locking in backref code
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 38e3eebff643db725633657d1d87a3be019d1018 upstream.
+
+Qgroups will do the old roots lookup at delayed ref time, which could be
+while walking down the extent root while running a delayed ref. This
+should be fine, except we specifically lock eb's in the backref walking
+code irrespective of path->skip_locking, which deadlocks the system.
+Fix up the backref code to honor path->skip_locking, nobody will be
+modifying the commit_root when we're searching so it's completely safe
+to do.
+
+This happens since fb235dc06fac ("btrfs: qgroup: Move half of the qgroup
+accounting time out of commit trans"), kernel may lockup with quota
+enabled.
+
+There is one backref trace triggered by snapshot dropping along with
+write operation in the source subvolume. The example can be reliably
+reproduced:
+
+ btrfs-cleaner D 0 4062 2 0x80000000
+ Call Trace:
+ schedule+0x32/0x90
+ btrfs_tree_read_lock+0x93/0x130 [btrfs]
+ find_parent_nodes+0x29b/0x1170 [btrfs]
+ btrfs_find_all_roots_safe+0xa8/0x120 [btrfs]
+ btrfs_find_all_roots+0x57/0x70 [btrfs]
+ btrfs_qgroup_trace_extent_post+0x37/0x70 [btrfs]
+ btrfs_qgroup_trace_leaf_items+0x10b/0x140 [btrfs]
+ btrfs_qgroup_trace_subtree+0xc8/0xe0 [btrfs]
+ do_walk_down+0x541/0x5e3 [btrfs]
+ walk_down_tree+0xab/0xe7 [btrfs]
+ btrfs_drop_snapshot+0x356/0x71a [btrfs]
+ btrfs_clean_one_deleted_snapshot+0xb8/0xf0 [btrfs]
+ cleaner_kthread+0x12b/0x160 [btrfs]
+ kthread+0x112/0x130
+ ret_from_fork+0x27/0x50
+
+When dropping snapshots with qgroup enabled, we will trigger backref
+walk.
+
+However such backref walk at that timing is pretty dangerous, as if one
+of the parent nodes get WRITE locked by other thread, we could cause a
+dead lock.
+
+For example:
+
+ FS 260 FS 261 (Dropped)
+ node A node B
+ / \ / \
+ node C node D node E
+ / \ / \ / \
+ leaf F|leaf G|leaf H|leaf I|leaf J|leaf K
+
+The lock sequence would be:
+
+ Thread A (cleaner) | Thread B (other writer)
+-----------------------------------------------------------------------
+write_lock(B) |
+write_lock(D) |
+^^^ called by walk_down_tree() |
+ | write_lock(A)
+ | write_lock(D) << Stall
+read_lock(H) << for backref walk |
+read_lock(D) << lock owner is |
+ the same thread A |
+ so read lock is OK |
+read_lock(A) << Stall |
+
+So thread A hold write lock D, and needs read lock A to unlock.
+While thread B holds write lock A, while needs lock D to unlock.
+
+This will cause a deadlock.
+
+This is not only limited to snapshot dropping case. As the backref
+walk, even only happens on commit trees, is breaking the normal top-down
+locking order, makes it deadlock prone.
+
+Fixes: fb235dc06fac ("btrfs: qgroup: Move half of the qgroup accounting time out of commit trans")
+CC: stable@vger.kernel.org # 4.14+
+Reported-and-tested-by: David Sterba <dsterba@suse.com>
+Reported-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+[ rebase to latest branch and fix lock assert bug in btrfs/007 ]
+[ backport to linux-4.19.y branch, solve minor conflicts ]
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+[ copy logs and deadlock analysis from Qu's patch ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/backref.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -710,7 +710,7 @@ out:
+ * read tree blocks and add keys where required.
+ */
+ static int add_missing_keys(struct btrfs_fs_info *fs_info,
+- struct preftrees *preftrees)
++ struct preftrees *preftrees, bool lock)
+ {
+ struct prelim_ref *ref;
+ struct extent_buffer *eb;
+@@ -735,12 +735,14 @@ static int add_missing_keys(struct btrfs
+ free_extent_buffer(eb);
+ return -EIO;
+ }
+- btrfs_tree_read_lock(eb);
++ if (lock)
++ btrfs_tree_read_lock(eb);
+ if (btrfs_header_level(eb) == 0)
+ btrfs_item_key_to_cpu(eb, &ref->key_for_search, 0);
+ else
+ btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
+- btrfs_tree_read_unlock(eb);
++ if (lock)
++ btrfs_tree_read_unlock(eb);
+ free_extent_buffer(eb);
+ prelim_ref_insert(fs_info, &preftrees->indirect, ref, NULL);
+ cond_resched();
+@@ -1225,7 +1227,7 @@ again:
+
+ btrfs_release_path(path);
+
+- ret = add_missing_keys(fs_info, &preftrees);
++ ret = add_missing_keys(fs_info, &preftrees, path->skip_locking == 0);
+ if (ret)
+ goto out;
+
+@@ -1286,11 +1288,14 @@ again:
+ ret = -EIO;
+ goto out;
+ }
+- btrfs_tree_read_lock(eb);
+- btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
++ if (!path->skip_locking) {
++ btrfs_tree_read_lock(eb);
++ btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
++ }
+ ret = find_extent_in_eb(eb, bytenr,
+ *extent_item_pos, &eie, ignore_offset);
+- btrfs_tree_read_unlock_blocking(eb);
++ if (!path->skip_locking)
++ btrfs_tree_read_unlock_blocking(eb);
+ free_extent_buffer(eb);
+ if (ret < 0)
+ goto out;