--- /dev/null
+From bffe3b3b9ce2755d8e32661d309336e7b75bd49d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Oct 2020 01:43:59 +0100
+Subject: ARM: 9019/1: kprobes: Avoid fortify_panic() when copying optprobe
+ template
+
+From: Andrew Jeffery <andrew@aj.id.au>
+
+[ Upstream commit 9fa2e7af3d53a4b769136eccc32c02e128a4ee51 ]
+
+Setting both CONFIG_KPROBES=y and CONFIG_FORTIFY_SOURCE=y on ARM leads
+to a panic in memcpy() when injecting a kprobe despite the fixes found
+in commit e46daee53bb5 ("ARM: 8806/1: kprobes: Fix false positive with
+FORTIFY_SOURCE") and commit 0ac569bf6a79 ("ARM: 8834/1: Fix: kprobes:
+optimized kprobes illegal instruction").
+
+arch/arm/include/asm/kprobes.h effectively declares
+the target type of the optprobe_template_entry assembly label as a u32
+which leads memcpy()'s __builtin_object_size() call to determine that
+the pointed-to object is of size four. However, the symbol is used as a handle
+for the optimised probe assembly template that is at least 96 bytes in size.
+The symbol's use despite its type blows up the memcpy() in ARM's
+arch_prepare_optimized_kprobe() with a false-positive fortify_panic() when it
+should instead copy the optimised probe template into place:
+
+```
+$ sudo perf probe -a aspeed_g6_pinctrl_probe
+[ 158.457252] detected buffer overflow in memcpy
+[ 158.458069] ------------[ cut here ]------------
+[ 158.458283] kernel BUG at lib/string.c:1153!
+[ 158.458436] Internal error: Oops - BUG: 0 [#1] SMP ARM
+[ 158.458768] Modules linked in:
+[ 158.459043] CPU: 1 PID: 99 Comm: perf Not tainted 5.9.0-rc7-00038-gc53ebf8167e9 #158
+[ 158.459296] Hardware name: Generic DT based system
+[ 158.459529] PC is at fortify_panic+0x18/0x20
+[ 158.459658] LR is at __irq_work_queue_local+0x3c/0x74
+[ 158.459831] pc : [<8047451c>] lr : [<8020ecd4>] psr: 60000013
+[ 158.460032] sp : be2d1d50 ip : be2d1c58 fp : be2d1d5c
+[ 158.460174] r10: 00000006 r9 : 00000000 r8 : 00000060
+[ 158.460348] r7 : 8011e434 r6 : b9e0b800 r5 : 7f000000 r4 : b9fe4f0c
+[ 158.460557] r3 : 80c04cc8 r2 : 00000000 r1 : be7c03cc r0 : 00000022
+[ 158.460801] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+[ 158.461037] Control: 10c5387d Table: b9cd806a DAC: 00000051
+[ 158.461251] Process perf (pid: 99, stack limit = 0x81c71a69)
+[ 158.461472] Stack: (0xbe2d1d50 to 0xbe2d2000)
+[ 158.461757] 1d40: be2d1d84 be2d1d60 8011e724 80474510
+[ 158.462104] 1d60: b9e0b800 b9fe4f0c 00000000 b9fe4f14 80c8ec80 be235000 be2d1d9c be2d1d88
+[ 158.462436] 1d80: 801cee44 8011e57c b9fe4f0c 00000000 be2d1dc4 be2d1da0 801d0ad0 801cedec
+[ 158.462742] 1da0: 00000000 00000000 b9fe4f00 ffffffea 00000000 be235000 be2d1de4 be2d1dc8
+[ 158.463087] 1dc0: 80204604 801d0738 00000000 00000000 b9fe4004 ffffffea be2d1e94 be2d1de8
+[ 158.463428] 1de0: 80205434 80204570 00385c00 00000000 00000000 00000000 be2d1e14 be2d1e08
+[ 158.463880] 1e00: 802ba014 b9fe4f00 b9e718c0 b9fe4f84 b9e71ec8 be2d1e24 00000000 00385c00
+[ 158.464365] 1e20: 00000000 626f7270 00000065 802b905c be2d1e94 0000002e 00000000 802b9914
+[ 158.464829] 1e40: be2d1e84 be2d1e50 802b9914 8028ff78 804629d0 b9e71ec0 0000002e b9e71ec0
+[ 158.465141] 1e60: be2d1ea8 80c04cc8 00000cc0 b9e713c4 00000002 80205834 80205834 0000002e
+[ 158.465488] 1e80: be235000 be235000 be2d1ea4 be2d1e98 80205854 80204e94 be2d1ecc be2d1ea8
+[ 158.465806] 1ea0: 801ee4a0 80205840 00000002 80c04cc8 00000000 0000002e 0000002e 00000000
+[ 158.466110] 1ec0: be2d1f0c be2d1ed0 801ee5c8 801ee428 00000000 be2d0000 006b1fd0 00000051
+[ 158.466398] 1ee0: 00000000 b9eedf00 0000002e 80204410 006b1fd0 be2d1f60 00000000 00000004
+[ 158.466763] 1f00: be2d1f24 be2d1f10 8020442c 801ee4c4 80205834 802c613c be2d1f5c be2d1f28
+[ 158.467102] 1f20: 802c60ac 8020441c be2d1fac be2d1f38 8010c764 802e9888 be2d1f5c b9eedf00
+[ 158.467447] 1f40: b9eedf00 006b1fd0 0000002e 00000000 be2d1f94 be2d1f60 802c634c 802c5fec
+[ 158.467812] 1f60: 00000000 00000000 00000000 80c04cc8 006b1fd0 00000003 76f7a610 00000004
+[ 158.468155] 1f80: 80100284 be2d0000 be2d1fa4 be2d1f98 802c63ec 802c62e8 00000000 be2d1fa8
+[ 158.468508] 1fa0: 80100080 802c63e0 006b1fd0 00000003 00000003 006b1fd0 0000002e 00000000
+[ 158.468858] 1fc0: 006b1fd0 00000003 76f7a610 00000004 006b1fb0 0026d348 00000017 7ef2738c
+[ 158.469202] 1fe0: 76f3431c 7ef272d8 0014ec50 76f34338 60000010 00000003 00000000 00000000
+[ 158.469461] Backtrace:
+[ 158.469683] [<80474504>] (fortify_panic) from [<8011e724>] (arch_prepare_optimized_kprobe+0x1b4/0x1f8)
+[ 158.470021] [<8011e570>] (arch_prepare_optimized_kprobe) from [<801cee44>] (alloc_aggr_kprobe+0x64/0x70)
+[ 158.470287] r9:be235000 r8:80c8ec80 r7:b9fe4f14 r6:00000000 r5:b9fe4f0c r4:b9e0b800
+[ 158.470478] [<801cede0>] (alloc_aggr_kprobe) from [<801d0ad0>] (register_kprobe+0x3a4/0x5a0)
+[ 158.470685] r5:00000000 r4:b9fe4f0c
+[ 158.470790] [<801d072c>] (register_kprobe) from [<80204604>] (__register_trace_kprobe+0xa0/0xa4)
+[ 158.471001] r9:be235000 r8:00000000 r7:ffffffea r6:b9fe4f00 r5:00000000 r4:00000000
+[ 158.471188] [<80204564>] (__register_trace_kprobe) from [<80205434>] (trace_kprobe_create+0x5ac/0x9ac)
+[ 158.471408] r7:ffffffea r6:b9fe4004 r5:00000000 r4:00000000
+[ 158.471553] [<80204e88>] (trace_kprobe_create) from [<80205854>] (create_or_delete_trace_kprobe+0x20/0x3c)
+[ 158.471766] r10:be235000 r9:be235000 r8:0000002e r7:80205834 r6:80205834 r5:00000002
+[ 158.471949] r4:b9e713c4
+[ 158.472027] [<80205834>] (create_or_delete_trace_kprobe) from [<801ee4a0>] (trace_run_command+0x84/0x9c)
+[ 158.472255] [<801ee41c>] (trace_run_command) from [<801ee5c8>] (trace_parse_run_command+0x110/0x1f8)
+[ 158.472471] r6:00000000 r5:0000002e r4:0000002e
+[ 158.472594] [<801ee4b8>] (trace_parse_run_command) from [<8020442c>] (probes_write+0x1c/0x28)
+[ 158.472800] r10:00000004 r9:00000000 r8:be2d1f60 r7:006b1fd0 r6:80204410 r5:0000002e
+[ 158.472968] r4:b9eedf00
+[ 158.473046] [<80204410>] (probes_write) from [<802c60ac>] (vfs_write+0xcc/0x1e8)
+[ 158.473226] [<802c5fe0>] (vfs_write) from [<802c634c>] (ksys_write+0x70/0xf8)
+[ 158.473400] r8:00000000 r7:0000002e r6:006b1fd0 r5:b9eedf00 r4:b9eedf00
+[ 158.473567] [<802c62dc>] (ksys_write) from [<802c63ec>] (sys_write+0x18/0x1c)
+[ 158.473745] r9:be2d0000 r8:80100284 r7:00000004 r6:76f7a610 r5:00000003 r4:006b1fd0
+[ 158.473932] [<802c63d4>] (sys_write) from [<80100080>] (ret_fast_syscall+0x0/0x54)
+[ 158.474126] Exception stack(0xbe2d1fa8 to 0xbe2d1ff0)
+[ 158.474305] 1fa0: 006b1fd0 00000003 00000003 006b1fd0 0000002e 00000000
+[ 158.474573] 1fc0: 006b1fd0 00000003 76f7a610 00000004 006b1fb0 0026d348 00000017 7ef2738c
+[ 158.474811] 1fe0: 76f3431c 7ef272d8 0014ec50 76f34338
+[ 158.475171] Code: e24cb004 e1a01000 e59f0004 ebf40dd3 (e7f001f2)
+[ 158.475847] ---[ end trace 55a5b31c08a29f00 ]---
+[ 158.476088] Kernel panic - not syncing: Fatal exception
+[ 158.476375] CPU0: stopping
+[ 158.476709] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G D 5.9.0-rc7-00038-gc53ebf8167e9 #158
+[ 158.477176] Hardware name: Generic DT based system
+[ 158.477411] Backtrace:
+[ 158.477604] [<8010dd28>] (dump_backtrace) from [<8010dfd4>] (show_stack+0x20/0x24)
+[ 158.477990] r7:00000000 r6:60000193 r5:00000000 r4:80c2f634
+[ 158.478323] [<8010dfb4>] (show_stack) from [<8046390c>] (dump_stack+0xcc/0xe8)
+[ 158.478686] [<80463840>] (dump_stack) from [<80110750>] (handle_IPI+0x334/0x3a0)
+[ 158.479063] r7:00000000 r6:00000004 r5:80b65cc8 r4:80c78278
+[ 158.479352] [<8011041c>] (handle_IPI) from [<801013f8>] (gic_handle_irq+0x88/0x94)
+[ 158.479757] r10:10c5387d r9:80c01ed8 r8:00000000 r7:c0802000 r6:80c0537c r5:000003ff
+[ 158.480146] r4:c080200c r3:fffffff4
+[ 158.480364] [<80101370>] (gic_handle_irq) from [<80100b6c>] (__irq_svc+0x6c/0x90)
+[ 158.480748] Exception stack(0x80c01ed8 to 0x80c01f20)
+[ 158.481031] 1ec0: 000128bc 00000000
+[ 158.481499] 1ee0: be7b8174 8011d3a0 80c00000 00000000 80c04cec 80c04d28 80c5d7c2 80a026d4
+[ 158.482091] 1f00: 10c5387d 80c01f34 80c01f38 80c01f28 80109554 80109558 60000013 ffffffff
+[ 158.482621] r9:80c00000 r8:80c5d7c2 r7:80c01f0c r6:ffffffff r5:60000013 r4:80109558
+[ 158.482983] [<80109518>] (arch_cpu_idle) from [<80818780>] (default_idle_call+0x38/0x120)
+[ 158.483360] [<80818748>] (default_idle_call) from [<801585a8>] (do_idle+0xd4/0x158)
+[ 158.483945] r5:00000000 r4:80c00000
+[ 158.484237] [<801584d4>] (do_idle) from [<801588f4>] (cpu_startup_entry+0x28/0x2c)
+[ 158.484784] r9:80c78000 r8:00000000 r7:80c78000 r6:80c78040 r5:80c04cc0 r4:000000d6
+[ 158.485328] [<801588cc>] (cpu_startup_entry) from [<80810a78>] (rest_init+0x9c/0xbc)
+[ 158.485930] [<808109dc>] (rest_init) from [<80b00ae4>] (arch_call_rest_init+0x18/0x1c)
+[ 158.486503] r5:80c04cc0 r4:00000001
+[ 158.486857] [<80b00acc>] (arch_call_rest_init) from [<80b00fcc>] (start_kernel+0x46c/0x548)
+[ 158.487589] [<80b00b60>] (start_kernel) from [<00000000>] (0x0)
+```
+
+Fixes: e46daee53bb5 ("ARM: 8806/1: kprobes: Fix false positive with FORTIFY_SOURCE")
+Fixes: 0ac569bf6a79 ("ARM: 8834/1: Fix: kprobes: optimized kprobes illegal instruction")
+Suggested-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
+Tested-by: Luka Oreskovic <luka.oreskovic@sartura.hr>
+Tested-by: Joel Stanley <joel@jms.id.au>
+Reviewed-by: Joel Stanley <joel@jms.id.au>
+Acked-by: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Luka Oreskovic <luka.oreskovic@sartura.hr>
+Cc: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/include/asm/kprobes.h | 22 +++++++++++-----------
+ arch/arm/probes/kprobes/opt-arm.c | 18 +++++++++---------
+ 2 files changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
+index 213607a1f45c1..e26a278d301ab 100644
+--- a/arch/arm/include/asm/kprobes.h
++++ b/arch/arm/include/asm/kprobes.h
+@@ -44,20 +44,20 @@ int kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data);
+
+ /* optinsn template addresses */
+-extern __visible kprobe_opcode_t optprobe_template_entry;
+-extern __visible kprobe_opcode_t optprobe_template_val;
+-extern __visible kprobe_opcode_t optprobe_template_call;
+-extern __visible kprobe_opcode_t optprobe_template_end;
+-extern __visible kprobe_opcode_t optprobe_template_sub_sp;
+-extern __visible kprobe_opcode_t optprobe_template_add_sp;
+-extern __visible kprobe_opcode_t optprobe_template_restore_begin;
+-extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn;
+-extern __visible kprobe_opcode_t optprobe_template_restore_end;
++extern __visible kprobe_opcode_t optprobe_template_entry[];
++extern __visible kprobe_opcode_t optprobe_template_val[];
++extern __visible kprobe_opcode_t optprobe_template_call[];
++extern __visible kprobe_opcode_t optprobe_template_end[];
++extern __visible kprobe_opcode_t optprobe_template_sub_sp[];
++extern __visible kprobe_opcode_t optprobe_template_add_sp[];
++extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
++extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
++extern __visible kprobe_opcode_t optprobe_template_restore_end[];
+
+ #define MAX_OPTIMIZED_LENGTH 4
+ #define MAX_OPTINSN_SIZE \
+- ((unsigned long)&optprobe_template_end - \
+- (unsigned long)&optprobe_template_entry)
++ ((unsigned long)optprobe_template_end - \
++ (unsigned long)optprobe_template_entry)
+ #define RELATIVEJUMP_SIZE 4
+
+ struct arch_optimized_insn {
+diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
+index 7a449df0b3591..c78180172120f 100644
+--- a/arch/arm/probes/kprobes/opt-arm.c
++++ b/arch/arm/probes/kprobes/opt-arm.c
+@@ -85,21 +85,21 @@ asm (
+ "optprobe_template_end:\n");
+
+ #define TMPL_VAL_IDX \
+- ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_val - (unsigned long *)optprobe_template_entry)
+ #define TMPL_CALL_IDX \
+- ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_call - (unsigned long *)optprobe_template_entry)
+ #define TMPL_END_IDX \
+- ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_end - (unsigned long *)optprobe_template_entry)
+ #define TMPL_ADD_SP \
+- ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_add_sp - (unsigned long *)optprobe_template_entry)
+ #define TMPL_SUB_SP \
+- ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_sub_sp - (unsigned long *)optprobe_template_entry)
+ #define TMPL_RESTORE_BEGIN \
+- ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_restore_begin - (unsigned long *)optprobe_template_entry)
+ #define TMPL_RESTORE_ORIGN_INSN \
+- ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_restore_orig_insn - (unsigned long *)optprobe_template_entry)
+ #define TMPL_RESTORE_END \
+- ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry)
++ ((unsigned long *)optprobe_template_restore_end - (unsigned long *)optprobe_template_entry)
+
+ /*
+ * ARM can always optimize an instruction when using ARM ISA, except
+@@ -234,7 +234,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *or
+ }
+
+ /* Copy arch-dep-instance from template. */
+- memcpy(code, (unsigned long *)&optprobe_template_entry,
++ memcpy(code, (unsigned long *)optprobe_template_entry,
+ TMPL_END_IDX * sizeof(kprobe_opcode_t));
+
+ /* Adjust buffer according to instruction. */
+--
+2.27.0
+
--- /dev/null
+From ee8983edc57cc2af76cb29f8d241d932b91fc7d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 28 Oct 2020 18:15:05 +0100
+Subject: bpf: Don't rely on GCC __attribute__((optimize)) to disable GCSE
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 080b6f40763565f65ebb9540219c71ce885cf568 ]
+
+Commit 3193c0836 ("bpf: Disable GCC -fgcse optimization for
+___bpf_prog_run()") introduced a __no_fgcse macro that expands to a
+function scope __attribute__((optimize("-fno-gcse"))), to disable a
+GCC specific optimization that was causing trouble on x86 builds, and
+was not expected to have any positive effect in the first place.
+
+However, as the GCC manual documents, __attribute__((optimize))
+is not for production use, and results in all other optimization
+options to be forgotten for the function in question. This can
+cause all kinds of trouble, but in one particular reported case,
+it causes -fno-asynchronous-unwind-tables to be disregarded,
+resulting in .eh_frame info to be emitted for the function.
+
+This reverts commit 3193c0836, and instead, it disables the -fgcse
+optimization for the entire source file, but only when building for
+X86 using GCC with CONFIG_BPF_JIT_ALWAYS_ON disabled. Note that the
+original commit states that CONFIG_RETPOLINE=n triggers the issue,
+whereas CONFIG_RETPOLINE=y performs better without the optimization,
+so it is kept disabled in both cases.
+
+Fixes: 3193c0836f20 ("bpf: Disable GCC -fgcse optimization for ___bpf_prog_run()")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Link: https://lore.kernel.org/lkml/CAMuHMdUg0WJHEcq6to0-eODpXPOywLot6UD2=GFHpzoj_hCoBQ@mail.gmail.com/
+Link: https://lore.kernel.org/bpf/20201028171506.15682-2-ardb@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/compiler-gcc.h | 2 --
+ include/linux/compiler_types.h | 4 ----
+ kernel/bpf/Makefile | 6 +++++-
+ kernel/bpf/core.c | 2 +-
+ 4 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
+index d7ee4c6bad482..e8579412ad214 100644
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -170,5 +170,3 @@
+ #else
+ #define __diag_GCC_8(s)
+ #endif
+-
+-#define __no_fgcse __attribute__((optimize("-fno-gcse")))
+diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
+index 72393a8c1a6c5..77433633572e4 100644
+--- a/include/linux/compiler_types.h
++++ b/include/linux/compiler_types.h
+@@ -212,10 +212,6 @@ struct ftrace_likely_data {
+ #define asm_inline asm
+ #endif
+
+-#ifndef __no_fgcse
+-# define __no_fgcse
+-#endif
+-
+ /* Are two types/vars the same type (ignoring qualifiers)? */
+ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
+
+diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
+index e1d9adb212f93..b0d78bc0b1979 100644
+--- a/kernel/bpf/Makefile
++++ b/kernel/bpf/Makefile
+@@ -1,6 +1,10 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-y := core.o
+-CFLAGS_core.o += $(call cc-disable-warning, override-init)
++ifneq ($(CONFIG_BPF_JIT_ALWAYS_ON),y)
++# ___bpf_prog_run() needs GCSE disabled on x86; see 3193c0836f203 for details
++cflags-nogcse-$(CONFIG_X86)$(CONFIG_CC_IS_GCC) := -fno-gcse
++endif
++CFLAGS_core.o += $(call cc-disable-warning, override-init) $(cflags-nogcse-yy)
+
+ obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o
+ obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index ef0e1e3e66f4a..56bc96f5ad208 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -1299,7 +1299,7 @@ bool bpf_opcode_in_insntable(u8 code)
+ *
+ * Decode and execute eBPF instructions.
+ */
+-static u64 __no_fgcse ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack)
++static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack)
+ {
+ #define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y
+ #define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z
+--
+2.27.0
+
--- /dev/null
+From 34ca7b321955347d2341d693efec5ce222938500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Nov 2020 12:23:32 +0100
+Subject: bpf: Zero-fill re-used per-cpu map element
+
+From: David Verbeiren <david.verbeiren@tessares.net>
+
+[ Upstream commit d3bec0138bfbe58606fc1d6f57a4cdc1a20218db ]
+
+Zero-fill element values for all other cpus than current, just as
+when not using prealloc. This is the only way the bpf program can
+ensure known initial values for all cpus ('onallcpus' cannot be
+set when coming from the bpf program).
+
+The scenario is: bpf program inserts some elements in a per-cpu
+map, then deletes some (or userspace does). When later adding
+new elements using bpf_map_update_elem(), the bpf program can
+only set the value of the new elements for the current cpu.
+When prealloc is enabled, previously deleted elements are re-used.
+Without the fix, values for other cpus remain whatever they were
+when the re-used entry was previously freed.
+
+A selftest is added to validate correct operation in above
+scenario as well as in case of LRU per-cpu map element re-use.
+
+Fixes: 6c9059817432 ("bpf: pre-allocate hash map elements")
+Signed-off-by: David Verbeiren <david.verbeiren@tessares.net>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Acked-by: Andrii Nakryiko <andrii@kernel.org>
+Link: https://lore.kernel.org/bpf/20201104112332.15191-1-david.verbeiren@tessares.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/hashtab.c | 30 ++-
+ .../selftests/bpf/prog_tests/map_init.c | 214 ++++++++++++++++++
+ .../selftests/bpf/progs/test_map_init.c | 33 +++
+ 3 files changed, 275 insertions(+), 2 deletions(-)
+ create mode 100644 tools/testing/selftests/bpf/prog_tests/map_init.c
+ create mode 100644 tools/testing/selftests/bpf/progs/test_map_init.c
+
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 728ffec52cf36..03a67583f6fb9 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -709,6 +709,32 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr,
+ }
+ }
+
++static void pcpu_init_value(struct bpf_htab *htab, void __percpu *pptr,
++ void *value, bool onallcpus)
++{
++ /* When using prealloc and not setting the initial value on all cpus,
++ * zero-fill element values for other cpus (just as what happens when
++ * not using prealloc). Otherwise, bpf program has no way to ensure
++ * known initial values for cpus other than current one
++ * (onallcpus=false always when coming from bpf prog).
++ */
++ if (htab_is_prealloc(htab) && !onallcpus) {
++ u32 size = round_up(htab->map.value_size, 8);
++ int current_cpu = raw_smp_processor_id();
++ int cpu;
++
++ for_each_possible_cpu(cpu) {
++ if (cpu == current_cpu)
++ bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value,
++ size);
++ else
++ memset(per_cpu_ptr(pptr, cpu), 0, size);
++ }
++ } else {
++ pcpu_copy_value(htab, pptr, value, onallcpus);
++ }
++}
++
+ static bool fd_htab_map_needs_adjust(const struct bpf_htab *htab)
+ {
+ return htab->map.map_type == BPF_MAP_TYPE_HASH_OF_MAPS &&
+@@ -779,7 +805,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
+ }
+ }
+
+- pcpu_copy_value(htab, pptr, value, onallcpus);
++ pcpu_init_value(htab, pptr, value, onallcpus);
+
+ if (!prealloc)
+ htab_elem_set_ptr(l_new, key_size, pptr);
+@@ -1075,7 +1101,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,
+ pcpu_copy_value(htab, htab_elem_get_ptr(l_old, key_size),
+ value, onallcpus);
+ } else {
+- pcpu_copy_value(htab, htab_elem_get_ptr(l_new, key_size),
++ pcpu_init_value(htab, htab_elem_get_ptr(l_new, key_size),
+ value, onallcpus);
+ hlist_nulls_add_head_rcu(&l_new->hash_node, head);
+ l_new = NULL;
+diff --git a/tools/testing/selftests/bpf/prog_tests/map_init.c b/tools/testing/selftests/bpf/prog_tests/map_init.c
+new file mode 100644
+index 0000000000000..14a31109dd0e0
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/map_init.c
+@@ -0,0 +1,214 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/* Copyright (c) 2020 Tessares SA <http://www.tessares.net> */
++
++#include <test_progs.h>
++#include "test_map_init.skel.h"
++
++#define TEST_VALUE 0x1234
++#define FILL_VALUE 0xdeadbeef
++
++static int nr_cpus;
++static int duration;
++
++typedef unsigned long long map_key_t;
++typedef unsigned long long map_value_t;
++typedef struct {
++ map_value_t v; /* padding */
++} __bpf_percpu_val_align pcpu_map_value_t;
++
++
++static int map_populate(int map_fd, int num)
++{
++ pcpu_map_value_t value[nr_cpus];
++ int i, err;
++ map_key_t key;
++
++ for (i = 0; i < nr_cpus; i++)
++ bpf_percpu(value, i) = FILL_VALUE;
++
++ for (key = 1; key <= num; key++) {
++ err = bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST);
++ if (!ASSERT_OK(err, "bpf_map_update_elem"))
++ return -1;
++ }
++
++ return 0;
++}
++
++static struct test_map_init *setup(enum bpf_map_type map_type, int map_sz,
++ int *map_fd, int populate)
++{
++ struct test_map_init *skel;
++ int err;
++
++ skel = test_map_init__open();
++ if (!ASSERT_OK_PTR(skel, "skel_open"))
++ return NULL;
++
++ err = bpf_map__set_type(skel->maps.hashmap1, map_type);
++ if (!ASSERT_OK(err, "bpf_map__set_type"))
++ goto error;
++
++ err = bpf_map__set_max_entries(skel->maps.hashmap1, map_sz);
++ if (!ASSERT_OK(err, "bpf_map__set_max_entries"))
++ goto error;
++
++ err = test_map_init__load(skel);
++ if (!ASSERT_OK(err, "skel_load"))
++ goto error;
++
++ *map_fd = bpf_map__fd(skel->maps.hashmap1);
++ if (CHECK(*map_fd < 0, "bpf_map__fd", "failed\n"))
++ goto error;
++
++ err = map_populate(*map_fd, populate);
++ if (!ASSERT_OK(err, "map_populate"))
++ goto error_map;
++
++ return skel;
++
++error_map:
++ close(*map_fd);
++error:
++ test_map_init__destroy(skel);
++ return NULL;
++}
++
++/* executes bpf program that updates map with key, value */
++static int prog_run_insert_elem(struct test_map_init *skel, map_key_t key,
++ map_value_t value)
++{
++ struct test_map_init__bss *bss;
++
++ bss = skel->bss;
++
++ bss->inKey = key;
++ bss->inValue = value;
++ bss->inPid = getpid();
++
++ if (!ASSERT_OK(test_map_init__attach(skel), "skel_attach"))
++ return -1;
++
++ /* Let tracepoint trigger */
++ syscall(__NR_getpgid);
++
++ test_map_init__detach(skel);
++
++ return 0;
++}
++
++static int check_values_one_cpu(pcpu_map_value_t *value, map_value_t expected)
++{
++ int i, nzCnt = 0;
++ map_value_t val;
++
++ for (i = 0; i < nr_cpus; i++) {
++ val = bpf_percpu(value, i);
++ if (val) {
++ if (CHECK(val != expected, "map value",
++ "unexpected for cpu %d: 0x%llx\n", i, val))
++ return -1;
++ nzCnt++;
++ }
++ }
++
++ if (CHECK(nzCnt != 1, "map value", "set for %d CPUs instead of 1!\n",
++ nzCnt))
++ return -1;
++
++ return 0;
++}
++
++/* Add key=1 elem with values set for all CPUs
++ * Delete elem key=1
++ * Run bpf prog that inserts new key=1 elem with value=0x1234
++ * (bpf prog can only set value for current CPU)
++ * Lookup Key=1 and check value is as expected for all CPUs:
++ * value set by bpf prog for one CPU, 0 for all others
++ */
++static void test_pcpu_map_init(void)
++{
++ pcpu_map_value_t value[nr_cpus];
++ struct test_map_init *skel;
++ int map_fd, err;
++ map_key_t key;
++
++ /* max 1 elem in map so insertion is forced to reuse freed entry */
++ skel = setup(BPF_MAP_TYPE_PERCPU_HASH, 1, &map_fd, 1);
++ if (!ASSERT_OK_PTR(skel, "prog_setup"))
++ return;
++
++ /* delete element so the entry can be re-used*/
++ key = 1;
++ err = bpf_map_delete_elem(map_fd, &key);
++ if (!ASSERT_OK(err, "bpf_map_delete_elem"))
++ goto cleanup;
++
++ /* run bpf prog that inserts new elem, re-using the slot just freed */
++ err = prog_run_insert_elem(skel, key, TEST_VALUE);
++ if (!ASSERT_OK(err, "prog_run_insert_elem"))
++ goto cleanup;
++
++ /* check that key=1 was re-created by bpf prog */
++ err = bpf_map_lookup_elem(map_fd, &key, value);
++ if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
++ goto cleanup;
++
++ /* and has expected values */
++ check_values_one_cpu(value, TEST_VALUE);
++
++cleanup:
++ test_map_init__destroy(skel);
++}
++
++/* Add key=1 and key=2 elems with values set for all CPUs
++ * Run bpf prog that inserts new key=3 elem
++ * (only for current cpu; other cpus should have initial value = 0)
++ * Lookup Key=1 and check value is as expected for all CPUs
++ */
++static void test_pcpu_lru_map_init(void)
++{
++ pcpu_map_value_t value[nr_cpus];
++ struct test_map_init *skel;
++ int map_fd, err;
++ map_key_t key;
++
++ /* Set up LRU map with 2 elements, values filled for all CPUs.
++ * With these 2 elements, the LRU map is full
++ */
++ skel = setup(BPF_MAP_TYPE_LRU_PERCPU_HASH, 2, &map_fd, 2);
++ if (!ASSERT_OK_PTR(skel, "prog_setup"))
++ return;
++
++ /* run bpf prog that inserts new key=3 element, re-using LRU slot */
++ key = 3;
++ err = prog_run_insert_elem(skel, key, TEST_VALUE);
++ if (!ASSERT_OK(err, "prog_run_insert_elem"))
++ goto cleanup;
++
++ /* check that key=3 replaced one of earlier elements */
++ err = bpf_map_lookup_elem(map_fd, &key, value);
++ if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
++ goto cleanup;
++
++ /* and has expected values */
++ check_values_one_cpu(value, TEST_VALUE);
++
++cleanup:
++ test_map_init__destroy(skel);
++}
++
++void test_map_init(void)
++{
++ nr_cpus = bpf_num_possible_cpus();
++ if (nr_cpus <= 1) {
++ printf("%s:SKIP: >1 cpu needed for this test\n", __func__);
++ test__skip();
++ return;
++ }
++
++ if (test__start_subtest("pcpu_map_init"))
++ test_pcpu_map_init();
++ if (test__start_subtest("pcpu_lru_map_init"))
++ test_pcpu_lru_map_init();
++}
+diff --git a/tools/testing/selftests/bpf/progs/test_map_init.c b/tools/testing/selftests/bpf/progs/test_map_init.c
+new file mode 100644
+index 0000000000000..c89d28ead6737
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/test_map_init.c
+@@ -0,0 +1,33 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2020 Tessares SA <http://www.tessares.net> */
++
++#include "vmlinux.h"
++#include <bpf/bpf_helpers.h>
++
++__u64 inKey = 0;
++__u64 inValue = 0;
++__u32 inPid = 0;
++
++struct {
++ __uint(type, BPF_MAP_TYPE_PERCPU_HASH);
++ __uint(max_entries, 2);
++ __type(key, __u64);
++ __type(value, __u64);
++} hashmap1 SEC(".maps");
++
++
++SEC("tp/syscalls/sys_enter_getpgid")
++int sysenter_getpgid(const void *ctx)
++{
++ /* Just do it for once, when called from our own test prog. This
++ * ensures the map value is only updated for a single CPU.
++ */
++ int cur_pid = bpf_get_current_pid_tgid() >> 32;
++
++ if (cur_pid == inPid)
++ bpf_map_update_elem(&hashmap1, &inKey, &inValue, BPF_NOEXIST);
++
++ return 0;
++}
++
++char _license[] SEC("license") = "GPL";
+--
+2.27.0
+
--- /dev/null
+From 19d220f6e84301bedf7dd7b4424d77850e67fe54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Nov 2020 22:46:14 +0800
+Subject: cosa: Add missing kfree in error path of cosa_write
+
+From: Wang Hai <wanghai38@huawei.com>
+
+[ Upstream commit 52755b66ddcef2e897778fac5656df18817b59ab ]
+
+If memory allocation for 'kbuf' succeed, cosa_write() doesn't have a
+corresponding kfree() in exception handling. Thus add kfree() for this
+function implementation.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Wang Hai <wanghai38@huawei.com>
+Acked-by: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
+Link: https://lore.kernel.org/r/20201110144614.43194-1-wanghai38@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wan/cosa.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
+index af539151d6638..61428076f32e4 100644
+--- a/drivers/net/wan/cosa.c
++++ b/drivers/net/wan/cosa.c
+@@ -889,6 +889,7 @@ static ssize_t cosa_write(struct file *file,
+ chan->tx_status = 1;
+ spin_unlock_irqrestore(&cosa->lock, flags);
+ up(&chan->wsem);
++ kfree(kbuf);
+ return -ERESTARTSYS;
+ }
+ }
+--
+2.27.0
+
--- /dev/null
+From 8871c32e4092666492247eb8f56e10f5c90b933d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Sep 2020 11:35:37 -0700
+Subject: igc: Fix returning wrong statistics
+
+From: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+
+[ Upstream commit 6b7ed22ae4c96a415001f0c3116ebee15bb8491a ]
+
+'igc_update_stats()' was not updating 'netdev->stats', so the returned
+statistics, for example, requested by:
+
+$ ip -s link show dev enp3s0
+
+were not being updated and were always zero.
+
+Fix by returning a set of statistics that are actually being
+updated (adapter->stats64).
+
+Fixes: c9a11c23ceb6 ("igc: Add netdev")
+Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/igc/igc_main.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index 24888676f69ba..6b43e1c5b1c3e 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -2222,21 +2222,23 @@ static int igc_change_mtu(struct net_device *netdev, int new_mtu)
+ }
+
+ /**
+- * igc_get_stats - Get System Network Statistics
++ * igc_get_stats64 - Get System Network Statistics
+ * @netdev: network interface device structure
++ * @stats: rtnl_link_stats64 pointer
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are updated here and also from the timer callback.
+ */
+-static struct net_device_stats *igc_get_stats(struct net_device *netdev)
++static void igc_get_stats64(struct net_device *netdev,
++ struct rtnl_link_stats64 *stats)
+ {
+ struct igc_adapter *adapter = netdev_priv(netdev);
+
++ spin_lock(&adapter->stats64_lock);
+ if (!test_bit(__IGC_RESETTING, &adapter->state))
+ igc_update_stats(adapter);
+-
+- /* only return the current stats */
+- return &netdev->stats;
++ memcpy(stats, &adapter->stats64, sizeof(*stats));
++ spin_unlock(&adapter->stats64_lock);
+ }
+
+ static netdev_features_t igc_fix_features(struct net_device *netdev,
+@@ -3984,7 +3986,7 @@ static const struct net_device_ops igc_netdev_ops = {
+ .ndo_start_xmit = igc_xmit_frame,
+ .ndo_set_mac_address = igc_set_mac,
+ .ndo_change_mtu = igc_change_mtu,
+- .ndo_get_stats = igc_get_stats,
++ .ndo_get_stats64 = igc_get_stats64,
+ .ndo_fix_features = igc_fix_features,
+ .ndo_set_features = igc_set_features,
+ .ndo_features_check = igc_features_check,
+--
+2.27.0
+
--- /dev/null
+From 70e35b1e11b2b05779f522520dfb482ef337a97c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Nov 2020 15:38:28 -0500
+Subject: lan743x: fix "BUG: invalid wait context" when setting rx mode
+
+From: Sven Van Asbroeck <thesven73@gmail.com>
+
+[ Upstream commit 2b52a4b65bc8f14520fe6e996ea7fb3f7e400761 ]
+
+In the net core, the struct net_device_ops -> ndo_set_rx_mode()
+callback is called with the dev->addr_list_lock spinlock held.
+
+However, this driver's ndo_set_rx_mode callback eventually calls
+lan743x_dp_write(), which acquires a mutex. Mutex acquisition
+may sleep, and this is not allowed when holding a spinlock.
+
+Fix by removing the dp_lock mutex entirely. Its purpose is to
+prevent concurrent accesses to the data port. No concurrent
+accesses are possible, because the dev->addr_list_lock
+spinlock in the core only lets through one thread at a time.
+
+Fixes: 23f0703c125b ("lan743x: Add main source files for new lan743x driver")
+Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
+Link: https://lore.kernel.org/r/20201109203828.5115-1-TheSven73@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/lan743x_main.c | 12 +++---------
+ drivers/net/ethernet/microchip/lan743x_main.h | 3 ---
+ 2 files changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
+index a43140f7b5eb8..b8e0e08b79de2 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.c
++++ b/drivers/net/ethernet/microchip/lan743x_main.c
+@@ -672,14 +672,12 @@ clean_up:
+ static int lan743x_dp_write(struct lan743x_adapter *adapter,
+ u32 select, u32 addr, u32 length, u32 *buf)
+ {
+- int ret = -EIO;
+ u32 dp_sel;
+ int i;
+
+- mutex_lock(&adapter->dp_lock);
+ if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
+ 1, 40, 100, 100))
+- goto unlock;
++ return -EIO;
+ dp_sel = lan743x_csr_read(adapter, DP_SEL);
+ dp_sel &= ~DP_SEL_MASK_;
+ dp_sel |= select;
+@@ -691,13 +689,10 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter,
+ lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_);
+ if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_,
+ 1, 40, 100, 100))
+- goto unlock;
++ return -EIO;
+ }
+- ret = 0;
+
+-unlock:
+- mutex_unlock(&adapter->dp_lock);
+- return ret;
++ return 0;
+ }
+
+ static u32 lan743x_mac_mii_access(u16 id, u16 index, int read)
+@@ -2674,7 +2669,6 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
+
+ adapter->intr.irq = adapter->pdev->irq;
+ lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF);
+- mutex_init(&adapter->dp_lock);
+
+ ret = lan743x_gpio_init(adapter);
+ if (ret)
+diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
+index 3b02eeae5f45d..1fbcef3910989 100644
+--- a/drivers/net/ethernet/microchip/lan743x_main.h
++++ b/drivers/net/ethernet/microchip/lan743x_main.h
+@@ -706,9 +706,6 @@ struct lan743x_adapter {
+ struct lan743x_csr csr;
+ struct lan743x_intr intr;
+
+- /* lock, used to prevent concurrent access to data port */
+- struct mutex dp_lock;
+-
+ struct lan743x_gpio gpio;
+ struct lan743x_ptp ptp;
+
+--
+2.27.0
+
--- /dev/null
+From ea422280b614be1c40e281fbcbb3305bec5bc05b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Nov 2020 18:30:59 +0100
+Subject: nbd: fix a block_device refcount leak in nbd_release
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 2bd645b2d3f0bacadaa6037f067538e1cd4e42ef ]
+
+bdget_disk needs to be paired with bdput to not leak a reference
+on the block device inode.
+
+Fixes: 08ba91ee6e2c ("nbd: Add the nbd NBD_DISCONNECT_ON_CLOSE config flag.")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/nbd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 62a873718b5bb..a3037fe54c3ab 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -1503,6 +1503,7 @@ static void nbd_release(struct gendisk *disk, fmode_t mode)
+ if (test_bit(NBD_RT_DISCONNECT_ON_CLOSE, &nbd->config->runtime_flags) &&
+ bdev->bd_openers == 0)
+ nbd_disconnect_and_put(nbd);
++ bdput(bdev);
+
+ nbd_config_put(nbd);
+ nbd_put(nbd);
+--
+2.27.0
+
--- /dev/null
+From e0cc4bb8ceba46a1e7746152b76c2f70327dec78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Oct 2020 08:42:49 +0300
+Subject: net/mlx5: Fix deletion of duplicate rules
+
+From: Maor Gottlieb <maorg@nvidia.com>
+
+[ Upstream commit 465e7baab6d93b399344f5868f84c177ab5cd16f ]
+
+When a rule is duplicated, the refcount of the rule is increased so only
+the second deletion of the rule should cause destruction of the FTE.
+Currently, the FTE will be destroyed in the first deletion of rule since
+the modify_mask will be 0.
+Fix it and call to destroy FTE only if all the rules (FTE's children)
+have been removed.
+
+Fixes: 718ce4d601db ("net/mlx5: Consolidate update FTE for all removal changes")
+Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 9ac2f52187ea4..16511f6485531 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -1923,10 +1923,11 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle)
+ down_write_ref_node(&fte->node, false);
+ for (i = handle->num_rules - 1; i >= 0; i--)
+ tree_remove_node(&handle->rule[i]->node, true);
+- if (fte->modify_mask && fte->dests_size) {
+- modify_fte(fte);
++ if (fte->dests_size) {
++ if (fte->modify_mask)
++ modify_fte(fte);
+ up_write_ref_node(&fte->node, false);
+- } else {
++ } else if (list_empty(&fte->node.children)) {
+ del_hw_fte(&fte->node);
+ /* Avoid double call to del_hw_fte */
+ fte->node.del_hw_func = NULL;
+--
+2.27.0
+
--- /dev/null
+From 2e139758d1983a66fd7f21aa3c6a91523a9193e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Nov 2020 15:28:25 +1300
+Subject: of/address: Fix of_node memory leak in of_dma_is_coherent
+
+From: Evan Nimmo <evan.nimmo@alliedtelesis.co.nz>
+
+[ Upstream commit a5bea04fcc0b3c0aec71ee1fd58fd4ff7ee36177 ]
+
+Commit dabf6b36b83a ("of: Add OF_DMA_DEFAULT_COHERENT & select it on
+powerpc") added a check to of_dma_is_coherent which returns early
+if OF_DMA_DEFAULT_COHERENT is enabled. This results in the of_node_put()
+being skipped causing a memory leak. Moved the of_node_get() below this
+check so we now we only get the node if OF_DMA_DEFAULT_COHERENT is not
+enabled.
+
+Fixes: dabf6b36b83a ("of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc")
+Signed-off-by: Evan Nimmo <evan.nimmo@alliedtelesis.co.nz>
+Link: https://lore.kernel.org/r/20201110022825.30895-1-evan.nimmo@alliedtelesis.co.nz
+Signed-off-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/address.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/of/address.c b/drivers/of/address.c
+index 8f74c4626e0ef..5abb056b2b515 100644
+--- a/drivers/of/address.c
++++ b/drivers/of/address.c
+@@ -1003,11 +1003,13 @@ EXPORT_SYMBOL_GPL(of_dma_get_range);
+ */
+ bool of_dma_is_coherent(struct device_node *np)
+ {
+- struct device_node *node = of_node_get(np);
++ struct device_node *node;
+
+ if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT))
+ return true;
+
++ node = of_node_get(np);
++
+ while (node) {
+ if (of_property_read_bool(node, "dma-coherent")) {
+ of_node_put(node);
+--
+2.27.0
+
--- /dev/null
+From 99dd2d87151489bf609e09d40b7794d022f4840d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Oct 2020 12:49:45 +0100
+Subject: perf: Fix get_recursion_context()
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit ce0f17fc93f63ee91428af10b7b2ddef38cd19e5 ]
+
+One should use in_serving_softirq() to detect SoftIRQ context.
+
+Fixes: 96f6d4444302 ("perf_counter: avoid recursion")
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20201030151955.120572175@infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/internal.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/events/internal.h b/kernel/events/internal.h
+index 3aef4191798c3..6e87b358e0826 100644
+--- a/kernel/events/internal.h
++++ b/kernel/events/internal.h
+@@ -210,7 +210,7 @@ static inline int get_recursion_context(int *recursion)
+ rctx = 3;
+ else if (in_irq())
+ rctx = 2;
+- else if (in_softirq())
++ else if (in_serving_softirq())
+ rctx = 1;
+ else
+ rctx = 0;
+--
+2.27.0
+
--- /dev/null
+From 0ee81992f8b69e9fd33e4cd669ab2c4015275c04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Oct 2020 13:54:50 +0800
+Subject: pinctrl: aspeed: Fix GPI only function problem.
+
+From: Billy Tsai <billy_tsai@aspeedtech.com>
+
+[ Upstream commit 9b92f5c51e9a41352d665f6f956bd95085a56a83 ]
+
+Some gpio pin at aspeed soc is input only and the prefix name of these
+pin is "GPI" only.
+This patch fine-tune the condition of GPIO check from "GPIO" to "GPI"
+and it will fix the usage error of banks D and E in the AST2400/AST2500
+and banks T and U in the AST2600.
+
+Fixes: 4d3d0e4272d8 ("pinctrl: Add core support for Aspeed SoCs")
+Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
+Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
+Link: https://lore.kernel.org/r/20201030055450.29613-1-billy_tsai@aspeedtech.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/aspeed/pinctrl-aspeed.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
+index 54933665b5f8b..93b5654ff2828 100644
+--- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c
++++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c
+@@ -277,13 +277,14 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
+ static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
+ {
+ /*
+- * The signal type is GPIO if the signal name has "GPIO" as a prefix.
++ * The signal type is GPIO if the signal name has "GPI" as a prefix.
+ * strncmp (rather than strcmp) is used to implement the prefix
+ * requirement.
+ *
+- * expr->signal might look like "GPIOT3" in the GPIO case.
++ * expr->signal might look like "GPIOB1" in the GPIO case.
++ * expr->signal might look like "GPIT0" in the GPI case.
+ */
+- return strncmp(expr->signal, "GPIO", 4) == 0;
++ return strncmp(expr->signal, "GPI", 3) == 0;
+ }
+
+ static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
+--
+2.27.0
+
--- /dev/null
+From 11d4672d1cb0fb39f00b6aebceeb1b8645d4bd0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Oct 2020 13:46:38 +0300
+Subject: pinctrl: intel: Set default bias in case no particular value given
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit f3c75e7a9349d1d33eb53ddc1b31640994969f73 ]
+
+When GPIO library asks pin control to set the bias, it doesn't pass
+any value of it and argument is considered boolean (and this is true
+for ACPI GpioIo() / GpioInt() resources, by the way). Thus, individual
+drivers must behave well, when they got the resistance value of 1 Ohm,
+i.e. transforming it to sane default.
+
+In case of Intel pin control hardware the 5 kOhm sounds plausible
+because on one hand it's a minimum of resistors present in all
+hardware generations and at the same time it's high enough to minimize
+leakage current (will be only 200 uA with the above choice).
+
+Fixes: e57725eabf87 ("pinctrl: intel: Add support for hardware debouncer")
+Reported-by: Jamie McClymont <jamie@kwiius.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/intel/pinctrl-intel.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index 83981ad66a71e..4e89bbf6b76a0 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -662,6 +662,10 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
+
+ value |= PADCFG1_TERM_UP;
+
++ /* Set default strength value in case none is given */
++ if (arg == 1)
++ arg = 5000;
++
+ switch (arg) {
+ case 20000:
+ value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+@@ -684,6 +688,10 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin,
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK);
+
++ /* Set default strength value in case none is given */
++ if (arg == 1)
++ arg = 5000;
++
+ switch (arg) {
+ case 20000:
+ value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT;
+--
+2.27.0
+
spi-bcm2835-remove-use-of-uninitialized-gpio-flags-variable.patch
tick-common-touch-watchdog-in-tick_unfreeze-on-all-cpus.patch
mfd-sprd-add-wakeup-capability-for-pmic-irq.patch
+pinctrl-intel-set-default-bias-in-case-no-particular.patch
+arm-9019-1-kprobes-avoid-fortify_panic-when-copying-.patch
+bpf-don-t-rely-on-gcc-__attribute__-optimize-to-disa.patch
+pinctrl-aspeed-fix-gpi-only-function-problem.patch
+net-mlx5-fix-deletion-of-duplicate-rules.patch
+sunrpc-fix-general-protection-fault-in-trace_rpc_xdr.patch
+bpf-zero-fill-re-used-per-cpu-map-element.patch
+nbd-fix-a-block_device-refcount-leak-in-nbd_release.patch
+igc-fix-returning-wrong-statistics.patch
+xfs-fix-flags-argument-to-rmap-lookup-when-convertin.patch
+xfs-set-the-unwritten-bit-in-rmap-lookup-flags-in-xc.patch
+xfs-fix-rmap-key-and-record-comparison-functions.patch
+xfs-fix-brainos-in-the-refcount-scrubber-s-rmap-frag.patch
+lan743x-fix-bug-invalid-wait-context-when-setting-rx.patch
+xfs-fix-a-missing-unlock-on-error-in-xfs_fs_map_bloc.patch
+of-address-fix-of_node-memory-leak-in-of_dma_is_cohe.patch
+cosa-add-missing-kfree-in-error-path-of-cosa_write.patch
+vrf-fix-fast-path-output-packet-handling-with-async-.patch
+perf-fix-get_recursion_context.patch
--- /dev/null
+From 214d5387b526f2fd6bd5da03397b682aea36aed0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 23 Oct 2020 10:41:07 -0400
+Subject: SUNRPC: Fix general protection fault in trace_rpc_xdr_overflow()
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+[ Upstream commit d321ff589c16d8c2207485a6d7fbdb14e873d46e ]
+
+The TP_fast_assign() section is careful enough not to dereference
+xdr->rqst if it's NULL. The TP_STRUCT__entry section is not.
+
+Fixes: 5582863f450c ("SUNRPC: Add XDR overflow trace event")
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/trace/events/sunrpc.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
+index 28df77a948e56..f16e9fb97e9f4 100644
+--- a/include/trace/events/sunrpc.h
++++ b/include/trace/events/sunrpc.h
+@@ -357,10 +357,10 @@ TRACE_EVENT(rpc_xdr_overflow,
+ __field(size_t, tail_len)
+ __field(unsigned int, page_len)
+ __field(unsigned int, len)
+- __string(progname,
+- xdr->rqst->rq_task->tk_client->cl_program->name)
+- __string(procedure,
+- xdr->rqst->rq_task->tk_msg.rpc_proc->p_name)
++ __string(progname, xdr->rqst ?
++ xdr->rqst->rq_task->tk_client->cl_program->name : "unknown")
++ __string(procedure, xdr->rqst ?
++ xdr->rqst->rq_task->tk_msg.rpc_proc->p_name : "unknown")
+ ),
+
+ TP_fast_assign(
+--
+2.27.0
+
--- /dev/null
+From b302c8dd4716fabf94dc6c83c0f671ffeebc7aa9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Nov 2020 08:30:30 +0100
+Subject: vrf: Fix fast path output packet handling with async Netfilter rules
+
+From: Martin Willi <martin@strongswan.org>
+
+[ Upstream commit 9e2b7fa2df4365e99934901da4fb4af52d81e820 ]
+
+VRF devices use an optimized direct path on output if a default qdisc
+is involved, calling Netfilter hooks directly. This path, however, does
+not consider Netfilter rules completing asynchronously, such as with
+NFQUEUE. The Netfilter okfn() is called for asynchronously accepted
+packets, but the VRF never passes that packet down the stack to send
+it out over the slave device. Using the slower redirect path for this
+seems not feasible, as we do not know beforehand if a Netfilter hook
+has asynchronously completing rules.
+
+Fix the use of asynchronously completing Netfilter rules in OUTPUT and
+POSTROUTING by using a special completion function that additionally
+calls dst_output() to pass the packet down the stack. Also, slightly
+adjust the use of nf_reset_ct() so that is called in the asynchronous
+case, too.
+
+Fixes: dcdd43c41e60 ("net: vrf: performance improvements for IPv4")
+Fixes: a9ec54d1b0cd ("net: vrf: performance improvements for IPv6")
+Signed-off-by: Martin Willi <martin@strongswan.org>
+Link: https://lore.kernel.org/r/20201106073030.3974927-1-martin@strongswan.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/vrf.c | 92 +++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 69 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 6716deeb35e33..0c7d746c03304 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -332,8 +332,7 @@ static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
+ return ret;
+ }
+
+-static int vrf_finish_direct(struct net *net, struct sock *sk,
+- struct sk_buff *skb)
++static void vrf_finish_direct(struct sk_buff *skb)
+ {
+ struct net_device *vrf_dev = skb->dev;
+
+@@ -352,7 +351,8 @@ static int vrf_finish_direct(struct net *net, struct sock *sk,
+ skb_pull(skb, ETH_HLEN);
+ }
+
+- return 1;
++ /* reset skb device */
++ nf_reset_ct(skb);
+ }
+
+ #if IS_ENABLED(CONFIG_IPV6)
+@@ -431,15 +431,41 @@ static struct sk_buff *vrf_ip6_out_redirect(struct net_device *vrf_dev,
+ return skb;
+ }
+
++static int vrf_output6_direct_finish(struct net *net, struct sock *sk,
++ struct sk_buff *skb)
++{
++ vrf_finish_direct(skb);
++
++ return vrf_ip6_local_out(net, sk, skb);
++}
++
+ static int vrf_output6_direct(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
+ {
++ int err = 1;
++
+ skb->protocol = htons(ETH_P_IPV6);
+
+- return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
+- net, sk, skb, NULL, skb->dev,
+- vrf_finish_direct,
+- !(IPCB(skb)->flags & IPSKB_REROUTED));
++ if (!(IPCB(skb)->flags & IPSKB_REROUTED))
++ err = nf_hook(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, sk, skb,
++ NULL, skb->dev, vrf_output6_direct_finish);
++
++ if (likely(err == 1))
++ vrf_finish_direct(skb);
++
++ return err;
++}
++
++static int vrf_ip6_out_direct_finish(struct net *net, struct sock *sk,
++ struct sk_buff *skb)
++{
++ int err;
++
++ err = vrf_output6_direct(net, sk, skb);
++ if (likely(err == 1))
++ err = vrf_ip6_local_out(net, sk, skb);
++
++ return err;
+ }
+
+ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
+@@ -452,18 +478,15 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
+ skb->dev = vrf_dev;
+
+ err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk,
+- skb, NULL, vrf_dev, vrf_output6_direct);
++ skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);
+
+ if (likely(err == 1))
+ err = vrf_output6_direct(net, sk, skb);
+
+- /* reset skb device */
+ if (likely(err == 1))
+- nf_reset_ct(skb);
+- else
+- skb = NULL;
++ return skb;
+
+- return skb;
++ return NULL;
+ }
+
+ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
+@@ -643,15 +666,41 @@ static struct sk_buff *vrf_ip_out_redirect(struct net_device *vrf_dev,
+ return skb;
+ }
+
++static int vrf_output_direct_finish(struct net *net, struct sock *sk,
++ struct sk_buff *skb)
++{
++ vrf_finish_direct(skb);
++
++ return vrf_ip_local_out(net, sk, skb);
++}
++
+ static int vrf_output_direct(struct net *net, struct sock *sk,
+ struct sk_buff *skb)
+ {
++ int err = 1;
++
+ skb->protocol = htons(ETH_P_IP);
+
+- return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING,
+- net, sk, skb, NULL, skb->dev,
+- vrf_finish_direct,
+- !(IPCB(skb)->flags & IPSKB_REROUTED));
++ if (!(IPCB(skb)->flags & IPSKB_REROUTED))
++ err = nf_hook(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, sk, skb,
++ NULL, skb->dev, vrf_output_direct_finish);
++
++ if (likely(err == 1))
++ vrf_finish_direct(skb);
++
++ return err;
++}
++
++static int vrf_ip_out_direct_finish(struct net *net, struct sock *sk,
++ struct sk_buff *skb)
++{
++ int err;
++
++ err = vrf_output_direct(net, sk, skb);
++ if (likely(err == 1))
++ err = vrf_ip_local_out(net, sk, skb);
++
++ return err;
+ }
+
+ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
+@@ -664,18 +713,15 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
+ skb->dev = vrf_dev;
+
+ err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk,
+- skb, NULL, vrf_dev, vrf_output_direct);
++ skb, NULL, vrf_dev, vrf_ip_out_direct_finish);
+
+ if (likely(err == 1))
+ err = vrf_output_direct(net, sk, skb);
+
+- /* reset skb device */
+ if (likely(err == 1))
+- nf_reset_ct(skb);
+- else
+- skb = NULL;
++ return skb;
+
+- return skb;
++ return NULL;
+ }
+
+ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
+--
+2.27.0
+
--- /dev/null
+From 179110a8226ed574a64d9a1e0e1d1c00b2ccff39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Nov 2020 08:07:37 -0800
+Subject: xfs: fix a missing unlock on error in xfs_fs_map_blocks
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 2bd3fa793aaa7e98b74e3653fdcc72fa753913b5 ]
+
+We also need to drop the iolock when invalidate_inode_pages2 fails, not
+only on all other error or successful cases.
+
+Fixes: 527851124d10 ("xfs: implement pNFS export operations")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_pnfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
+index a339bd5fa2604..f63fe8d924a36 100644
+--- a/fs/xfs/xfs_pnfs.c
++++ b/fs/xfs/xfs_pnfs.c
+@@ -134,7 +134,7 @@ xfs_fs_map_blocks(
+ goto out_unlock;
+ error = invalidate_inode_pages2(inode->i_mapping);
+ if (WARN_ON_ONCE(error))
+- return error;
++ goto out_unlock;
+
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + length);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+--
+2.27.0
+
--- /dev/null
+From d4c2b09f2b5343c45f0a0995c1c8f2c13cdd2caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Nov 2020 16:32:42 -0800
+Subject: xfs: fix brainos in the refcount scrubber's rmap fragment processor
+
+From: Darrick J. Wong <darrick.wong@oracle.com>
+
+[ Upstream commit 54e9b09e153842ab5adb8a460b891e11b39e9c3d ]
+
+Fix some serious WTF in the reference count scrubber's rmap fragment
+processing. The code comment says that this loop is supposed to move
+all fragment records starting at or before bno onto the worklist, but
+there's no obvious reason why nr (the number of items added) should
+increment starting from 1, and breaking the loop when we've added the
+target number seems dubious since we could have more rmap fragments that
+should have been added to the worklist.
+
+This seems to manifest in xfs/411 when adding one to the refcount field.
+
+Fixes: dbde19da9637 ("xfs: cross-reference the rmapbt data with the refcountbt")
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/scrub/refcount.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c
+index 0cab11a5d3907..5c6b71b75ca10 100644
+--- a/fs/xfs/scrub/refcount.c
++++ b/fs/xfs/scrub/refcount.c
+@@ -170,7 +170,6 @@ xchk_refcountbt_process_rmap_fragments(
+ */
+ INIT_LIST_HEAD(&worklist);
+ rbno = NULLAGBLOCK;
+- nr = 1;
+
+ /* Make sure the fragments actually /are/ in agbno order. */
+ bno = 0;
+@@ -184,15 +183,14 @@ xchk_refcountbt_process_rmap_fragments(
+ * Find all the rmaps that start at or before the refc extent,
+ * and put them on the worklist.
+ */
++ nr = 0;
+ list_for_each_entry_safe(frag, n, &refchk->fragments, list) {
+- if (frag->rm.rm_startblock > refchk->bno)
+- goto done;
++ if (frag->rm.rm_startblock > refchk->bno || nr > target_nr)
++ break;
+ bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;
+ if (bno < rbno)
+ rbno = bno;
+ list_move_tail(&frag->list, &worklist);
+- if (nr == target_nr)
+- break;
+ nr++;
+ }
+
+--
+2.27.0
+
--- /dev/null
+From 65247a0a616470094e6ff3ad4bfebd02e6533963 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Nov 2020 16:32:43 -0800
+Subject: xfs: fix flags argument to rmap lookup when converting shared file
+ rmaps
+
+From: Darrick J. Wong <darrick.wong@oracle.com>
+
+[ Upstream commit ea8439899c0b15a176664df62aff928010fad276 ]
+
+Pass the same oldext argument (which contains the existing rmapping's
+unwritten state) to xfs_rmap_lookup_le_range at the start of
+xfs_rmap_convert_shared. At this point in the code, flags is zero,
+which means that we perform lookups using the wrong key.
+
+Fixes: 3f165b334e51 ("xfs: convert unwritten status of reverse mappings for shared files")
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/libxfs/xfs_rmap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
+index 38e9414878b3e..9d3c67b654ca7 100644
+--- a/fs/xfs/libxfs/xfs_rmap.c
++++ b/fs/xfs/libxfs/xfs_rmap.c
+@@ -1379,7 +1379,7 @@ xfs_rmap_convert_shared(
+ * record for our insertion point. This will also give us the record for
+ * start block contiguity tests.
+ */
+- error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, flags,
++ error = xfs_rmap_lookup_le_range(cur, bno, owner, offset, oldext,
+ &PREV, &i);
+ if (error)
+ goto done;
+--
+2.27.0
+
--- /dev/null
+From 8ece6629e68124baaa1e565bea0d1253c97be2ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Nov 2020 16:32:44 -0800
+Subject: xfs: fix rmap key and record comparison functions
+
+From: Darrick J. Wong <darrick.wong@oracle.com>
+
+[ Upstream commit 6ff646b2ceb0eec916101877f38da0b73e3a5b7f ]
+
+Keys for extent interval records in the reverse mapping btree are
+supposed to be computed as follows:
+
+(physical block, owner, fork, is_btree, is_unwritten, offset)
+
+This provides users the ability to look up a reverse mapping from a bmbt
+record -- start with the physical block; then if there are multiple
+records for the same block, move on to the owner; then the inode fork
+type; and so on to the file offset.
+
+However, the key comparison functions incorrectly remove the
+fork/btree/unwritten information that's encoded in the on-disk offset.
+This means that lookup comparisons are only done with:
+
+(physical block, owner, offset)
+
+This means that queries can return incorrect results. On consistent
+filesystems this hasn't been an issue because blocks are never shared
+between forks or with bmbt blocks; and are never unwritten. However,
+this bug means that online repair cannot always detect corruption in the
+key information in internal rmapbt nodes.
+
+Found by fuzzing keys[1].attrfork = ones on xfs/371.
+
+Fixes: 4b8ed67794fe ("xfs: add rmap btree operations")
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/libxfs/xfs_rmap_btree.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
+index fc78efa52c94e..3780609c7860c 100644
+--- a/fs/xfs/libxfs/xfs_rmap_btree.c
++++ b/fs/xfs/libxfs/xfs_rmap_btree.c
+@@ -243,8 +243,8 @@ xfs_rmapbt_key_diff(
+ else if (y > x)
+ return -1;
+
+- x = XFS_RMAP_OFF(be64_to_cpu(kp->rm_offset));
+- y = rec->rm_offset;
++ x = be64_to_cpu(kp->rm_offset);
++ y = xfs_rmap_irec_offset_pack(rec);
+ if (x > y)
+ return 1;
+ else if (y > x)
+@@ -275,8 +275,8 @@ xfs_rmapbt_diff_two_keys(
+ else if (y > x)
+ return -1;
+
+- x = XFS_RMAP_OFF(be64_to_cpu(kp1->rm_offset));
+- y = XFS_RMAP_OFF(be64_to_cpu(kp2->rm_offset));
++ x = be64_to_cpu(kp1->rm_offset);
++ y = be64_to_cpu(kp2->rm_offset);
+ if (x > y)
+ return 1;
+ else if (y > x)
+@@ -390,8 +390,8 @@ xfs_rmapbt_keys_inorder(
+ return 1;
+ else if (a > b)
+ return 0;
+- a = XFS_RMAP_OFF(be64_to_cpu(k1->rmap.rm_offset));
+- b = XFS_RMAP_OFF(be64_to_cpu(k2->rmap.rm_offset));
++ a = be64_to_cpu(k1->rmap.rm_offset);
++ b = be64_to_cpu(k2->rmap.rm_offset);
+ if (a <= b)
+ return 1;
+ return 0;
+@@ -420,8 +420,8 @@ xfs_rmapbt_recs_inorder(
+ return 1;
+ else if (a > b)
+ return 0;
+- a = XFS_RMAP_OFF(be64_to_cpu(r1->rmap.rm_offset));
+- b = XFS_RMAP_OFF(be64_to_cpu(r2->rmap.rm_offset));
++ a = be64_to_cpu(r1->rmap.rm_offset);
++ b = be64_to_cpu(r2->rmap.rm_offset);
+ if (a <= b)
+ return 1;
+ return 0;
+--
+2.27.0
+
--- /dev/null
+From 494f3820402ff86fa00c63c2a8afbdb63647c7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Nov 2020 16:32:43 -0800
+Subject: xfs: set the unwritten bit in rmap lookup flags in
+ xchk_bmap_get_rmapextents
+
+From: Darrick J. Wong <darrick.wong@oracle.com>
+
+[ Upstream commit 5dda3897fd90783358c4c6115ef86047d8c8f503 ]
+
+When the bmbt scrubber is looking up rmap extents, we need to set the
+extent flags from the bmbt record fully. This will matter once we fix
+the rmap btree comparison functions to check those flags correctly.
+
+Fixes: d852657ccfc0 ("xfs: cross-reference reverse-mapping btree")
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/scrub/bmap.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
+index 392fb4df5c127..ec580c0d70fa3 100644
+--- a/fs/xfs/scrub/bmap.c
++++ b/fs/xfs/scrub/bmap.c
+@@ -113,6 +113,8 @@ xchk_bmap_get_rmap(
+
+ if (info->whichfork == XFS_ATTR_FORK)
+ rflags |= XFS_RMAP_ATTR_FORK;
++ if (irec->br_state == XFS_EXT_UNWRITTEN)
++ rflags |= XFS_RMAP_UNWRITTEN;
+
+ /*
+ * CoW staging extents are owned (on disk) by the refcountbt, so
+--
+2.27.0
+