From: Sasha Levin Date: Mon, 16 Nov 2020 13:58:16 +0000 (-0500) Subject: Fixes for 5.4 X-Git-Tag: v4.4.244~56 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2bb33a1095fb608e5b3ed94e5d8780b8b7805d28;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/arm-9019-1-kprobes-avoid-fortify_panic-when-copying-.patch b/queue-5.4/arm-9019-1-kprobes-avoid-fortify_panic-when-copying-.patch new file mode 100644 index 00000000000..f45b60e6271 --- /dev/null +++ b/queue-5.4/arm-9019-1-kprobes-avoid-fortify_panic-when-copying-.patch @@ -0,0 +1,228 @@ +From bffe3b3b9ce2755d8e32661d309336e7b75bd49d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Oct 2020 01:43:59 +0100 +Subject: ARM: 9019/1: kprobes: Avoid fortify_panic() when copying optprobe + template + +From: Andrew Jeffery + +[ 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 +Signed-off-by: Andrew Jeffery +Tested-by: Luka Oreskovic +Tested-by: Joel Stanley +Reviewed-by: Joel Stanley +Acked-by: Masami Hiramatsu +Cc: Luka Oreskovic +Cc: Juraj Vijtiuk +Signed-off-by: Russell King +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/bpf-don-t-rely-on-gcc-__attribute__-optimize-to-disa.patch b/queue-5.4/bpf-don-t-rely-on-gcc-__attribute__-optimize-to-disa.patch new file mode 100644 index 00000000000..54b15e3b0ce --- /dev/null +++ b/queue-5.4/bpf-don-t-rely-on-gcc-__attribute__-optimize-to-disa.patch @@ -0,0 +1,101 @@ +From ee8983edc57cc2af76cb29f8d241d932b91fc7d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Oct 2020 18:15:05 +0100 +Subject: bpf: Don't rely on GCC __attribute__((optimize)) to disable GCSE + +From: Ard Biesheuvel + +[ 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 +Signed-off-by: Alexei Starovoitov +Tested-by: Geert Uytterhoeven +Reviewed-by: Nick Desaulniers +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 +--- + 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 + diff --git a/queue-5.4/bpf-zero-fill-re-used-per-cpu-map-element.patch b/queue-5.4/bpf-zero-fill-re-used-per-cpu-map-element.patch new file mode 100644 index 00000000000..8279bb77219 --- /dev/null +++ b/queue-5.4/bpf-zero-fill-re-used-per-cpu-map-element.patch @@ -0,0 +1,357 @@ +From 34ca7b321955347d2341d693efec5ce222938500 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Nov 2020 12:23:32 +0100 +Subject: bpf: Zero-fill re-used per-cpu map element + +From: David Verbeiren + +[ 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 +Signed-off-by: Alexei Starovoitov +Acked-by: Matthieu Baerts +Acked-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20201104112332.15191-1-david.verbeiren@tessares.net +Signed-off-by: Sasha Levin +--- + 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 */ ++ ++#include ++#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 */ ++ ++#include "vmlinux.h" ++#include ++ ++__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 + diff --git a/queue-5.4/cosa-add-missing-kfree-in-error-path-of-cosa_write.patch b/queue-5.4/cosa-add-missing-kfree-in-error-path-of-cosa_write.patch new file mode 100644 index 00000000000..db3a28805e5 --- /dev/null +++ b/queue-5.4/cosa-add-missing-kfree-in-error-path-of-cosa_write.patch @@ -0,0 +1,39 @@ +From 19d220f6e84301bedf7dd7b4424d77850e67fe54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Nov 2020 22:46:14 +0800 +Subject: cosa: Add missing kfree in error path of cosa_write + +From: Wang Hai + +[ 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 +Signed-off-by: Wang Hai +Acked-by: Jan "Yenya" Kasprzak +Link: https://lore.kernel.org/r/20201110144614.43194-1-wanghai38@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/igc-fix-returning-wrong-statistics.patch b/queue-5.4/igc-fix-returning-wrong-statistics.patch new file mode 100644 index 00000000000..b03eb27fd09 --- /dev/null +++ b/queue-5.4/igc-fix-returning-wrong-statistics.patch @@ -0,0 +1,73 @@ +From 8871c32e4092666492247eb8f56e10f5c90b933d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Sep 2020 11:35:37 -0700 +Subject: igc: Fix returning wrong statistics + +From: Vinicius Costa Gomes + +[ 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 +Tested-by: Aaron Brown +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/lan743x-fix-bug-invalid-wait-context-when-setting-rx.patch b/queue-5.4/lan743x-fix-bug-invalid-wait-context-when-setting-rx.patch new file mode 100644 index 00000000000..888b4cebda2 --- /dev/null +++ b/queue-5.4/lan743x-fix-bug-invalid-wait-context-when-setting-rx.patch @@ -0,0 +1,92 @@ +From 70e35b1e11b2b05779f522520dfb482ef337a97c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Nov 2020 15:38:28 -0500 +Subject: lan743x: fix "BUG: invalid wait context" when setting rx mode + +From: Sven Van Asbroeck + +[ 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 +Link: https://lore.kernel.org/r/20201109203828.5115-1-TheSven73@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/nbd-fix-a-block_device-refcount-leak-in-nbd_release.patch b/queue-5.4/nbd-fix-a-block_device-refcount-leak-in-nbd_release.patch new file mode 100644 index 00000000000..c6dde54632a --- /dev/null +++ b/queue-5.4/nbd-fix-a-block_device-refcount-leak-in-nbd_release.patch @@ -0,0 +1,36 @@ +From ea422280b614be1c40e281fbcbb3305bec5bc05b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Nov 2020 18:30:59 +0100 +Subject: nbd: fix a block_device refcount leak in nbd_release + +From: Christoph Hellwig + +[ 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 +Reviewed-by: Josef Bacik +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/net-mlx5-fix-deletion-of-duplicate-rules.patch b/queue-5.4/net-mlx5-fix-deletion-of-duplicate-rules.patch new file mode 100644 index 00000000000..9b2f15e7b34 --- /dev/null +++ b/queue-5.4/net-mlx5-fix-deletion-of-duplicate-rules.patch @@ -0,0 +1,47 @@ +From e0cc4bb8ceba46a1e7746152b76c2f70327dec78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Oct 2020 08:42:49 +0300 +Subject: net/mlx5: Fix deletion of duplicate rules + +From: Maor Gottlieb + +[ 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 +Reviewed-by: Mark Bloch +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/of-address-fix-of_node-memory-leak-in-of_dma_is_cohe.patch b/queue-5.4/of-address-fix-of_node-memory-leak-in-of_dma_is_cohe.patch new file mode 100644 index 00000000000..85a3016aec2 --- /dev/null +++ b/queue-5.4/of-address-fix-of_node-memory-leak-in-of_dma_is_cohe.patch @@ -0,0 +1,47 @@ +From 2e139758d1983a66fd7f21aa3c6a91523a9193e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20201110022825.30895-1-evan.nimmo@alliedtelesis.co.nz +Signed-off-by: Rob Herring +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/perf-fix-get_recursion_context.patch b/queue-5.4/perf-fix-get_recursion_context.patch new file mode 100644 index 00000000000..dabc098ced4 --- /dev/null +++ b/queue-5.4/perf-fix-get_recursion_context.patch @@ -0,0 +1,35 @@ +From 99dd2d87151489bf609e09d40b7794d022f4840d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Oct 2020 12:49:45 +0100 +Subject: perf: Fix get_recursion_context() + +From: Peter Zijlstra + +[ 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) +Link: https://lkml.kernel.org/r/20201030151955.120572175@infradead.org +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/pinctrl-aspeed-fix-gpi-only-function-problem.patch b/queue-5.4/pinctrl-aspeed-fix-gpi-only-function-problem.patch new file mode 100644 index 00000000000..c661cce7c3d --- /dev/null +++ b/queue-5.4/pinctrl-aspeed-fix-gpi-only-function-problem.patch @@ -0,0 +1,50 @@ +From 0ee81992f8b69e9fd33e4cd669ab2c4015275c04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 30 Oct 2020 13:54:50 +0800 +Subject: pinctrl: aspeed: Fix GPI only function problem. + +From: Billy Tsai + +[ 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 +Reviewed-by: Andrew Jeffery +Link: https://lore.kernel.org/r/20201030055450.29613-1-billy_tsai@aspeedtech.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/pinctrl-intel-set-default-bias-in-case-no-particular.patch b/queue-5.4/pinctrl-intel-set-default-bias-in-case-no-particular.patch new file mode 100644 index 00000000000..0c40e6f657f --- /dev/null +++ b/queue-5.4/pinctrl-intel-set-default-bias-in-case-no-particular.patch @@ -0,0 +1,58 @@ +From 11d4672d1cb0fb39f00b6aebceeb1b8645d4bd0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Oct 2020 13:46:38 +0300 +Subject: pinctrl: intel: Set default bias in case no particular value given + +From: Andy Shevchenko + +[ 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 +Signed-off-by: Andy Shevchenko +Acked-by: Mika Westerberg +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/series b/queue-5.4/series index 6a0776d4d61..0fd6158c595 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -84,3 +84,22 @@ tpm_tis-disable-interrupts-on-thinkpad-t490s.patch 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 diff --git a/queue-5.4/sunrpc-fix-general-protection-fault-in-trace_rpc_xdr.patch b/queue-5.4/sunrpc-fix-general-protection-fault-in-trace_rpc_xdr.patch new file mode 100644 index 00000000000..588d949fbca --- /dev/null +++ b/queue-5.4/sunrpc-fix-general-protection-fault-in-trace_rpc_xdr.patch @@ -0,0 +1,42 @@ +From 214d5387b526f2fd6bd5da03397b682aea36aed0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Oct 2020 10:41:07 -0400 +Subject: SUNRPC: Fix general protection fault in trace_rpc_xdr_overflow() + +From: Chuck Lever + +[ 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 +Signed-off-by: J. Bruce Fields +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/vrf-fix-fast-path-output-packet-handling-with-async-.patch b/queue-5.4/vrf-fix-fast-path-output-packet-handling-with-async-.patch new file mode 100644 index 00000000000..82fbf456680 --- /dev/null +++ b/queue-5.4/vrf-fix-fast-path-output-packet-handling-with-async-.patch @@ -0,0 +1,197 @@ +From b302c8dd4716fabf94dc6c83c0f671ffeebc7aa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 6 Nov 2020 08:30:30 +0100 +Subject: vrf: Fix fast path output packet handling with async Netfilter rules + +From: Martin Willi + +[ 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 +Link: https://lore.kernel.org/r/20201106073030.3974927-1-martin@strongswan.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/xfs-fix-a-missing-unlock-on-error-in-xfs_fs_map_bloc.patch b/queue-5.4/xfs-fix-a-missing-unlock-on-error-in-xfs_fs_map_bloc.patch new file mode 100644 index 00000000000..c802f95852b --- /dev/null +++ b/queue-5.4/xfs-fix-a-missing-unlock-on-error-in-xfs_fs_map_bloc.patch @@ -0,0 +1,37 @@ +From 179110a8226ed574a64d9a1e0e1d1c00b2ccff39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/xfs-fix-brainos-in-the-refcount-scrubber-s-rmap-frag.patch b/queue-5.4/xfs-fix-brainos-in-the-refcount-scrubber-s-rmap-frag.patch new file mode 100644 index 00000000000..1aed180add1 --- /dev/null +++ b/queue-5.4/xfs-fix-brainos-in-the-refcount-scrubber-s-rmap-frag.patch @@ -0,0 +1,61 @@ +From d4c2b09f2b5343c45f0a0995c1c8f2c13cdd2caf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/xfs-fix-flags-argument-to-rmap-lookup-when-convertin.patch b/queue-5.4/xfs-fix-flags-argument-to-rmap-lookup-when-convertin.patch new file mode 100644 index 00000000000..0dd74e805dd --- /dev/null +++ b/queue-5.4/xfs-fix-flags-argument-to-rmap-lookup-when-convertin.patch @@ -0,0 +1,39 @@ +From 65247a0a616470094e6ff3ad4bfebd02e6533963 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/xfs-fix-rmap-key-and-record-comparison-functions.patch b/queue-5.4/xfs-fix-rmap-key-and-record-comparison-functions.patch new file mode 100644 index 00000000000..3ee769b4f2b --- /dev/null +++ b/queue-5.4/xfs-fix-rmap-key-and-record-comparison-functions.patch @@ -0,0 +1,92 @@ +From 8ece6629e68124baaa1e565bea0d1253c97be2ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 8 Nov 2020 16:32:44 -0800 +Subject: xfs: fix rmap key and record comparison functions + +From: Darrick J. Wong + +[ 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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.4/xfs-set-the-unwritten-bit-in-rmap-lookup-flags-in-xc.patch b/queue-5.4/xfs-set-the-unwritten-bit-in-rmap-lookup-flags-in-xc.patch new file mode 100644 index 00000000000..033ae244142 --- /dev/null +++ b/queue-5.4/xfs-set-the-unwritten-bit-in-rmap-lookup-flags-in-xc.patch @@ -0,0 +1,38 @@ +From 494f3820402ff86fa00c63c2a8afbdb63647c7d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + 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 +