From 6f076414aeb6d7cc238076f690066f8a72127adf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Dec 2021 12:42:48 +0100 Subject: [PATCH] 5.15-stable patches added patches: arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch bpf-fix-extable-address-check.patch bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch media-mxl111sf-change-mutex_init-location.patch mptcp-add-missing-documented-nl-params.patch usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch --- ...nc-fix-csi_data07__esai_tx0-pad-name.patch | 37 +++ .../bpf-fix-extable-address-check.patch | 92 ++++++ ...t-emission-of-rex-byte-in-more-cases.patch | 122 +++++++ ...ref-after-subvolume-creation-failure.patch | 309 ------------------ ...-mxl111sf-change-mutex_init-location.patch | 112 +++++++ ...tcp-add-missing-documented-nl-params.patch | 53 +++ queue-5.15/series | 8 +- ...oc_control-and-do_proc_bulk-killable.patch | 304 +++++++++++++++++ ...t-sleep-in-poll-when-need_wakeup-set.patch | 52 +++ 9 files changed, 779 insertions(+), 310 deletions(-) create mode 100644 queue-5.15/arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch create mode 100644 queue-5.15/bpf-fix-extable-address-check.patch create mode 100644 queue-5.15/bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch delete mode 100644 queue-5.15/btrfs-fix-invalid-delayed-ref-after-subvolume-creation-failure.patch create mode 100644 queue-5.15/media-mxl111sf-change-mutex_init-location.patch create mode 100644 queue-5.15/mptcp-add-missing-documented-nl-params.patch create mode 100644 queue-5.15/usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch create mode 100644 queue-5.15/xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch diff --git a/queue-5.15/arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch b/queue-5.15/arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch new file mode 100644 index 00000000000..40d0dbf5152 --- /dev/null +++ b/queue-5.15/arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch @@ -0,0 +1,37 @@ +From 737e65c7956795b3553781fb7bc82fce1c39503f Mon Sep 17 00:00:00 2001 +From: Fabio Estevam +Date: Wed, 24 Nov 2021 15:45:41 -0300 +Subject: ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name + +From: Fabio Estevam + +commit 737e65c7956795b3553781fb7bc82fce1c39503f upstream. + +According to the i.MX6ULL Reference Manual, pad CSI_DATA07 may +have the ESAI_TX0 functionality, not ESAI_T0. + +Also, NXP's i.MX Config Tools 10.0 generates dtsi with the +MX6ULL_PAD_CSI_DATA07__ESAI_TX0 naming, so fix it accordingly. + +There are no devicetree users in mainline that use the old name, +so just remove the old entry. + +Fixes: c201369d4aa5 ("ARM: dts: imx6ull: add imx6ull support") +Reported-by: George Makarov +Signed-off-by: Fabio Estevam +Signed-off-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/boot/dts/imx6ull-pinfunc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/boot/dts/imx6ull-pinfunc.h ++++ b/arch/arm/boot/dts/imx6ull-pinfunc.h +@@ -82,6 +82,6 @@ + #define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0 + #define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0 + #define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0 +-#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0 ++#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0 0x0200 0x048C 0x0000 0x9 0x0 + + #endif /* __DTS_IMX6ULL_PINFUNC_H */ diff --git a/queue-5.15/bpf-fix-extable-address-check.patch b/queue-5.15/bpf-fix-extable-address-check.patch new file mode 100644 index 00000000000..8c71e4505f1 --- /dev/null +++ b/queue-5.15/bpf-fix-extable-address-check.patch @@ -0,0 +1,92 @@ +From 588a25e92458c6efeb7a261d5ca5726f5de89184 Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov +Date: Tue, 14 Dec 2021 19:25:13 -0800 +Subject: bpf: Fix extable address check. + +From: Alexei Starovoitov + +commit 588a25e92458c6efeb7a261d5ca5726f5de89184 upstream. + +The verifier checks that PTR_TO_BTF_ID pointer is either valid or NULL, +but it cannot distinguish IS_ERR pointer from valid one. + +When offset is added to IS_ERR pointer it may become small positive +value which is a user address that is not handled by extable logic +and has to be checked for at the runtime. + +Tighten BPF_PROBE_MEM pointer check code to prevent this case. + +Fixes: 4c5de127598e ("bpf: Emit explicit NULL pointer checks for PROBE_LDX instructions.") +Reported-by: Lorenzo Fontana +Signed-off-by: Alexei Starovoitov +Acked-by: Daniel Borkmann +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/net/bpf_jit_comp.c | 49 +++++++++++++++++++++++++++++++++++++------- + 1 file changed, 42 insertions(+), 7 deletions(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1280,19 +1280,54 @@ st: if (is_imm8(insn->off)) + case BPF_LDX | BPF_MEM | BPF_DW: + case BPF_LDX | BPF_PROBE_MEM | BPF_DW: + if (BPF_MODE(insn->code) == BPF_PROBE_MEM) { +- /* test src_reg, src_reg */ +- maybe_emit_mod(&prog, src_reg, src_reg, true); /* always 1 byte */ +- EMIT2(0x85, add_2reg(0xC0, src_reg, src_reg)); +- /* jne start_of_ldx */ +- EMIT2(X86_JNE, 0); ++ /* Though the verifier prevents negative insn->off in BPF_PROBE_MEM ++ * add abs(insn->off) to the limit to make sure that negative ++ * offset won't be an issue. ++ * insn->off is s16, so it won't affect valid pointers. ++ */ ++ u64 limit = TASK_SIZE_MAX + PAGE_SIZE + abs(insn->off); ++ u8 *end_of_jmp1, *end_of_jmp2; ++ ++ /* Conservatively check that src_reg + insn->off is a kernel address: ++ * 1. src_reg + insn->off >= limit ++ * 2. src_reg + insn->off doesn't become small positive. ++ * Cannot do src_reg + insn->off >= limit in one branch, ++ * since it needs two spare registers, but JIT has only one. ++ */ ++ ++ /* movabsq r11, limit */ ++ EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG)); ++ EMIT((u32)limit, 4); ++ EMIT(limit >> 32, 4); ++ /* cmp src_reg, r11 */ ++ maybe_emit_mod(&prog, src_reg, AUX_REG, true); ++ EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG)); ++ /* if unsigned '<' goto end_of_jmp2 */ ++ EMIT2(X86_JB, 0); ++ end_of_jmp1 = prog; ++ ++ /* mov r11, src_reg */ ++ emit_mov_reg(&prog, true, AUX_REG, src_reg); ++ /* add r11, insn->off */ ++ maybe_emit_1mod(&prog, AUX_REG, true); ++ EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off); ++ /* jmp if not carry to start_of_ldx ++ * Otherwise ERR_PTR(-EINVAL) + 128 will be the user addr ++ * that has to be rejected. ++ */ ++ EMIT2(0x73 /* JNC */, 0); ++ end_of_jmp2 = prog; ++ + /* xor dst_reg, dst_reg */ + emit_mov_imm32(&prog, false, dst_reg, 0); + /* jmp byte_after_ldx */ + EMIT2(0xEB, 0); + +- /* populate jmp_offset for JNE above */ +- temp[4] = prog - temp - 5 /* sizeof(test + jne) */; ++ /* populate jmp_offset for JB above to jump to xor dst_reg */ ++ end_of_jmp1[-1] = end_of_jmp2 - end_of_jmp1; ++ /* populate jmp_offset for JNC above to jump to start_of_ldx */ + start_of_ldx = prog; ++ end_of_jmp2[-1] = start_of_ldx - end_of_jmp2; + } + emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off); + if (BPF_MODE(insn->code) == BPF_PROBE_MEM) { diff --git a/queue-5.15/bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch b/queue-5.15/bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch new file mode 100644 index 00000000000..e3b6a2cb2af --- /dev/null +++ b/queue-5.15/bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch @@ -0,0 +1,122 @@ +From 6364d7d75a0e015a405d1f8a07f267f076c36ca6 Mon Sep 17 00:00:00 2001 +From: Jie Meng +Date: Wed, 6 Oct 2021 12:41:35 -0700 +Subject: bpf, x64: Factor out emission of REX byte in more cases + +From: Jie Meng + +commit 6364d7d75a0e015a405d1f8a07f267f076c36ca6 upstream. + +Introduce a single reg version of maybe_emit_mod() and factor out +common code in more cases. + +Signed-off-by: Jie Meng +Signed-off-by: Daniel Borkmann +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20211006194135.608932-1-jmeng@fb.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/net/bpf_jit_comp.c | 50 ++++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 24 deletions(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -721,6 +721,20 @@ static void maybe_emit_mod(u8 **pprog, u + *pprog = prog; + } + ++/* ++ * Similar version of maybe_emit_mod() for a single register ++ */ ++static void maybe_emit_1mod(u8 **pprog, u32 reg, bool is64) ++{ ++ u8 *prog = *pprog; ++ ++ if (is64) ++ EMIT1(add_1mod(0x48, reg)); ++ else if (is_ereg(reg)) ++ EMIT1(add_1mod(0x40, reg)); ++ *pprog = prog; ++} ++ + /* LDX: dst_reg = *(u8*)(src_reg + off) */ + static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off) + { +@@ -951,10 +965,8 @@ static int do_jit(struct bpf_prog *bpf_p + /* neg dst */ + case BPF_ALU | BPF_NEG: + case BPF_ALU64 | BPF_NEG: +- if (BPF_CLASS(insn->code) == BPF_ALU64) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_ALU64); + EMIT2(0xF7, add_1reg(0xD8, dst_reg)); + break; + +@@ -968,10 +980,8 @@ static int do_jit(struct bpf_prog *bpf_p + case BPF_ALU64 | BPF_AND | BPF_K: + case BPF_ALU64 | BPF_OR | BPF_K: + case BPF_ALU64 | BPF_XOR | BPF_K: +- if (BPF_CLASS(insn->code) == BPF_ALU64) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_ALU64); + + /* + * b3 holds 'normal' opcode, b2 short form only valid +@@ -1112,10 +1122,8 @@ static int do_jit(struct bpf_prog *bpf_p + case BPF_ALU64 | BPF_LSH | BPF_K: + case BPF_ALU64 | BPF_RSH | BPF_K: + case BPF_ALU64 | BPF_ARSH | BPF_K: +- if (BPF_CLASS(insn->code) == BPF_ALU64) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_ALU64); + + b3 = simple_alu_opcodes[BPF_OP(insn->code)]; + if (imm32 == 1) +@@ -1146,10 +1154,8 @@ static int do_jit(struct bpf_prog *bpf_p + } + + /* shl %rax, %cl | shr %rax, %cl | sar %rax, %cl */ +- if (BPF_CLASS(insn->code) == BPF_ALU64) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_ALU64); + + b3 = simple_alu_opcodes[BPF_OP(insn->code)]; + EMIT2(0xD3, add_1reg(b3, dst_reg)); +@@ -1459,10 +1465,8 @@ st: if (is_imm8(insn->off)) + case BPF_JMP | BPF_JSET | BPF_K: + case BPF_JMP32 | BPF_JSET | BPF_K: + /* test dst_reg, imm32 */ +- if (BPF_CLASS(insn->code) == BPF_JMP) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_JMP); + EMIT2_off32(0xF7, add_1reg(0xC0, dst_reg), imm32); + goto emit_cond_jmp; + +@@ -1495,10 +1499,8 @@ st: if (is_imm8(insn->off)) + } + + /* cmp dst_reg, imm8/32 */ +- if (BPF_CLASS(insn->code) == BPF_JMP) +- EMIT1(add_1mod(0x48, dst_reg)); +- else if (is_ereg(dst_reg)) +- EMIT1(add_1mod(0x40, dst_reg)); ++ maybe_emit_1mod(&prog, dst_reg, ++ BPF_CLASS(insn->code) == BPF_JMP); + + if (is_imm8(imm32)) + EMIT3(0x83, add_1reg(0xF8, dst_reg), imm32); diff --git a/queue-5.15/btrfs-fix-invalid-delayed-ref-after-subvolume-creation-failure.patch b/queue-5.15/btrfs-fix-invalid-delayed-ref-after-subvolume-creation-failure.patch deleted file mode 100644 index a27e55d2260..00000000000 --- a/queue-5.15/btrfs-fix-invalid-delayed-ref-after-subvolume-creation-failure.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 7a1636089acfee7562fe79aff7d1b4c57869896d Mon Sep 17 00:00:00 2001 -From: Filipe Manana -Date: Mon, 13 Dec 2021 08:45:12 +0000 -Subject: btrfs: fix invalid delayed ref after subvolume creation failure - -From: Filipe Manana - -commit 7a1636089acfee7562fe79aff7d1b4c57869896d upstream. - -When creating a subvolume, at ioctl.c:create_subvol(), if we fail to -insert the new root's root item into the root tree, we are freeing the -metadata extent we reserved for the new root to prevent a metadata -extent leak, as we don't abort the transaction at that point (since -there is nothing at that point that is irreversible). - -However we allocated the metadata extent for the new root which we are -creating for the new subvolume, so its delayed reference refers to the -ID of this new root. But when we free the metadata extent we pass the -root of the subvolume where the new subvolume is located to -btrfs_free_tree_block() - this is incorrect because this will generate -a delayed reference that refers to the ID of the parent subvolume's root, -and not to ID of the new root. - -This results in a failure when running delayed references that leads to -a transaction abort and a trace like the following: - -[3868.738042] RIP: 0010:__btrfs_free_extent+0x709/0x950 [btrfs] -[3868.739857] Code: 68 0f 85 e6 fb ff (...) -[3868.742963] RSP: 0018:ffffb0e9045cf910 EFLAGS: 00010246 -[3868.743908] RAX: 00000000fffffffe RBX: 00000000fffffffe RCX: 0000000000000002 -[3868.745312] RDX: 00000000fffffffe RSI: 0000000000000002 RDI: ffff90b0cd793b88 -[3868.746643] RBP: 000000000e5d8000 R08: 0000000000000000 R09: ffff90b0cd793b88 -[3868.747979] R10: 0000000000000002 R11: 00014ded97944d68 R12: 0000000000000000 -[3868.749373] R13: ffff90b09afe4a28 R14: 0000000000000000 R15: ffff90b0cd793b88 -[3868.750725] FS: 00007f281c4a8b80(0000) GS:ffff90b3ada00000(0000) knlGS:0000000000000000 -[3868.752275] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 -[3868.753515] CR2: 00007f281c6a5000 CR3: 0000000108a42006 CR4: 0000000000370ee0 -[3868.754869] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 -[3868.756228] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 -[3868.757803] Call Trace: -[3868.758281] -[3868.758655] ? btrfs_merge_delayed_refs+0x178/0x1c0 [btrfs] -[3868.759827] __btrfs_run_delayed_refs+0x2b1/0x1250 [btrfs] -[3868.761047] btrfs_run_delayed_refs+0x86/0x210 [btrfs] -[3868.762069] ? lock_acquired+0x19f/0x420 -[3868.762829] btrfs_commit_transaction+0x69/0xb20 [btrfs] -[3868.763860] ? _raw_spin_unlock+0x29/0x40 -[3868.764614] ? btrfs_block_rsv_release+0x1c2/0x1e0 [btrfs] -[3868.765870] create_subvol+0x1d8/0x9a0 [btrfs] -[3868.766766] btrfs_mksubvol+0x447/0x4c0 [btrfs] -[3868.767669] ? preempt_count_add+0x49/0xa0 -[3868.768444] __btrfs_ioctl_snap_create+0x123/0x190 [btrfs] -[3868.769639] ? _copy_from_user+0x66/0xa0 -[3868.770391] btrfs_ioctl_snap_create_v2+0xbb/0x140 [btrfs] -[3868.771495] btrfs_ioctl+0xd1e/0x35c0 [btrfs] -[3868.772364] ? __slab_free+0x10a/0x360 -[3868.773198] ? rcu_read_lock_sched_held+0x12/0x60 -[3868.774121] ? lock_release+0x223/0x4a0 -[3868.774863] ? lock_acquired+0x19f/0x420 -[3868.775634] ? rcu_read_lock_sched_held+0x12/0x60 -[3868.776530] ? trace_hardirqs_on+0x1b/0xe0 -[3868.777373] ? _raw_spin_unlock_irqrestore+0x3e/0x60 -[3868.778280] ? kmem_cache_free+0x321/0x3c0 -[3868.779011] ? __x64_sys_ioctl+0x83/0xb0 -[3868.779718] __x64_sys_ioctl+0x83/0xb0 -[3868.780387] do_syscall_64+0x3b/0xc0 -[3868.781059] entry_SYSCALL_64_after_hwframe+0x44/0xae -[3868.781953] RIP: 0033:0x7f281c59e957 -[3868.782585] Code: 3c 1c 48 f7 d8 4c (...) -[3868.785867] RSP: 002b:00007ffe1f83e2b8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010 -[3868.787198] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f281c59e957 -[3868.788450] RDX: 00007ffe1f83e2c0 RSI: 0000000050009418 RDI: 0000000000000003 -[3868.789748] RBP: 00007ffe1f83f300 R08: 0000000000000000 R09: 00007ffe1f83fe36 -[3868.791214] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000003 -[3868.792468] R13: 0000000000000003 R14: 00007ffe1f83e2c0 R15: 00000000000003cc -[3868.793765] -[3868.794037] irq event stamp: 0 -[3868.794548] hardirqs last enabled at (0): [<0000000000000000>] 0x0 -[3868.795670] hardirqs last disabled at (0): [] copy_process+0x934/0x2040 -[3868.797086] softirqs last enabled at (0): [] copy_process+0x934/0x2040 -[3868.798309] softirqs last disabled at (0): [<0000000000000000>] 0x0 -[3868.799284] ---[ end trace be24c7002fe27747 ]--- -[3868.799928] BTRFS info (device dm-0): leaf 241188864 gen 1268 total ptrs 214 free space 469 owner 2 -[3868.801133] BTRFS info (device dm-0): refs 2 lock_owner 225627 current 225627 -[3868.802056] item 0 key (237436928 169 0) itemoff 16250 itemsize 33 -[3868.802863] extent refs 1 gen 1265 flags 2 -[3868.803447] ref#0: tree block backref root 1610 -(...) -[3869.064354] item 114 key (241008640 169 0) itemoff 12488 itemsize 33 -[3869.065421] extent refs 1 gen 1268 flags 2 -[3869.066115] ref#0: tree block backref root 1689 -(...) -[3869.403834] BTRFS error (device dm-0): unable to find ref byte nr 241008640 parent 0 root 1622 owner 0 offset 0 -[3869.405641] BTRFS: error (device dm-0) in __btrfs_free_extent:3076: errno=-2 No such entry -[3869.407138] BTRFS: error (device dm-0) in btrfs_run_delayed_refs:2159: errno=-2 No such entry - -Fix this by passing the new subvolume's root ID to btrfs_free_tree_block(). -This requires changing the root argument of btrfs_free_tree_block() from -struct btrfs_root * to a u64, since at this point during the subvolume -creation we have not yet created the struct btrfs_root for the new -subvolume, and btrfs_free_tree_block() only needs a root ID and nothing -else from a struct btrfs_root. - -This was triggered by test case generic/475 from fstests. - -Fixes: 67addf29004c5b ("btrfs: fix metadata extent leak after failure to create subvolume") -CC: stable@vger.kernel.org # 4.4+ -Reviewed-by: Nikolay Borisov -Signed-off-by: Filipe Manana -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman ---- - fs/btrfs/ctree.c | 17 +++++++++-------- - fs/btrfs/ctree.h | 7 ++++++- - fs/btrfs/extent-tree.c | 13 +++++++------ - fs/btrfs/free-space-tree.c | 4 ++-- - fs/btrfs/ioctl.c | 9 +++++---- - fs/btrfs/qgroup.c | 3 ++- - 6 files changed, 31 insertions(+), 22 deletions(-) - -diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c -index 74c8e18f3720..64599625c7d7 100644 ---- a/fs/btrfs/ctree.c -+++ b/fs/btrfs/ctree.c -@@ -462,8 +462,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, - BUG_ON(ret < 0); - rcu_assign_pointer(root->node, cow); - -- btrfs_free_tree_block(trans, root, buf, parent_start, -- last_ref); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), buf, -+ parent_start, last_ref); - free_extent_buffer(buf); - add_root_to_dirty_list(root); - } else { -@@ -484,8 +484,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, - return ret; - } - } -- btrfs_free_tree_block(trans, root, buf, parent_start, -- last_ref); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), buf, -+ parent_start, last_ref); - } - if (unlock_orig) - btrfs_tree_unlock(buf); -@@ -926,7 +926,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, - free_extent_buffer(mid); - - root_sub_used(root, mid->len); -- btrfs_free_tree_block(trans, root, mid, 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); - /* once for the root ptr */ - free_extent_buffer_stale(mid); - return 0; -@@ -985,7 +985,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, - btrfs_tree_unlock(right); - del_ptr(root, path, level + 1, pslot + 1); - root_sub_used(root, right->len); -- btrfs_free_tree_block(trans, root, right, 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), right, -+ 0, 1); - free_extent_buffer_stale(right); - right = NULL; - } else { -@@ -1030,7 +1031,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, - btrfs_tree_unlock(mid); - del_ptr(root, path, level + 1, pslot); - root_sub_used(root, mid->len); -- btrfs_free_tree_block(trans, root, mid, 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); - free_extent_buffer_stale(mid); - mid = NULL; - } else { -@@ -4031,7 +4032,7 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans, - root_sub_used(root, leaf->len); - - atomic_inc(&leaf->refs); -- btrfs_free_tree_block(trans, root, leaf, 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1); - free_extent_buffer_stale(leaf); - } - /* -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 7553e9dc5f93..5fe5eccb3c87 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -2257,6 +2257,11 @@ static inline bool btrfs_root_dead(const struct btrfs_root *root) - return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0; - } - -+static inline u64 btrfs_root_id(const struct btrfs_root *root) -+{ -+ return root->root_key.objectid; -+} -+ - /* struct btrfs_root_backup */ - BTRFS_SETGET_STACK_FUNCS(backup_tree_root, struct btrfs_root_backup, - tree_root, 64); -@@ -2719,7 +2724,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, - u64 empty_size, - enum btrfs_lock_nesting nest); - void btrfs_free_tree_block(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -+ u64 root_id, - struct extent_buffer *buf, - u64 parent, int last_ref); - int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index fc4895e6a62c..25ef6e3fd306 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -3275,20 +3275,20 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, - } - - void btrfs_free_tree_block(struct btrfs_trans_handle *trans, -- struct btrfs_root *root, -+ u64 root_id, - struct extent_buffer *buf, - u64 parent, int last_ref) - { -- struct btrfs_fs_info *fs_info = root->fs_info; -+ struct btrfs_fs_info *fs_info = trans->fs_info; - struct btrfs_ref generic_ref = { 0 }; - int ret; - - btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF, - buf->start, buf->len, parent); - btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf), -- root->root_key.objectid, 0, false); -+ root_id, 0, false); - -- if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { -+ if (root_id != BTRFS_TREE_LOG_OBJECTID) { - btrfs_ref_tree_mod(fs_info, &generic_ref); - ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL); - BUG_ON(ret); /* -ENOMEM */ -@@ -3298,7 +3298,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_block_group *cache; - bool must_pin = false; - -- if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { -+ if (root_id != BTRFS_TREE_LOG_OBJECTID) { - ret = check_ref_cleanup(trans, buf->start); - if (!ret) { - btrfs_redirty_list_add(trans->transaction, buf); -@@ -5472,7 +5472,8 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, - goto owner_mismatch; - } - -- btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(root), eb, parent, -+ wc->refs[level] == 1); - out: - wc->refs[level] = 0; - wc->flags[level] = 0; -diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c -index a33bca94d133..3abec44c6255 100644 ---- a/fs/btrfs/free-space-tree.c -+++ b/fs/btrfs/free-space-tree.c -@@ -1256,8 +1256,8 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) - btrfs_tree_lock(free_space_root->node); - btrfs_clean_tree_block(free_space_root->node); - btrfs_tree_unlock(free_space_root->node); -- btrfs_free_tree_block(trans, free_space_root, free_space_root->node, -- 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(free_space_root), -+ free_space_root->node, 0, 1); - - btrfs_put_root(free_space_root); - -diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c -index 1b85d98df66b..a7533416370a 100644 ---- a/fs/btrfs/ioctl.c -+++ b/fs/btrfs/ioctl.c -@@ -617,11 +617,12 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, - * Since we don't abort the transaction in this case, free the - * tree block so that we don't leak space and leave the - * filesystem in an inconsistent state (an extent item in the -- * extent tree without backreferences). Also no need to have -- * the tree block locked since it is not in any tree at this -- * point, so no other task can find it and use it. -+ * extent tree with a backreference for a root that does not -+ * exists). Also no need to have the tree block locked since it -+ * is not in any tree at this point, so no other task can find -+ * it and use it. - */ -- btrfs_free_tree_block(trans, root, leaf, 0, 1); -+ btrfs_free_tree_block(trans, objectid, leaf, 0, 1); - free_extent_buffer(leaf); - goto fail; - } -diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c -index db680f5be745..6c037f1252b7 100644 ---- a/fs/btrfs/qgroup.c -+++ b/fs/btrfs/qgroup.c -@@ -1219,7 +1219,8 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info) - btrfs_tree_lock(quota_root->node); - btrfs_clean_tree_block(quota_root->node); - btrfs_tree_unlock(quota_root->node); -- btrfs_free_tree_block(trans, quota_root, quota_root->node, 0, 1); -+ btrfs_free_tree_block(trans, btrfs_root_id(quota_root), -+ quota_root->node, 0, 1); - - btrfs_put_root(quota_root); - --- -2.34.1 - diff --git a/queue-5.15/media-mxl111sf-change-mutex_init-location.patch b/queue-5.15/media-mxl111sf-change-mutex_init-location.patch new file mode 100644 index 00000000000..b40ad88913b --- /dev/null +++ b/queue-5.15/media-mxl111sf-change-mutex_init-location.patch @@ -0,0 +1,112 @@ +From 44870a9e7a3c24acbb3f888b2a7cc22c9bdf7e7f Mon Sep 17 00:00:00 2001 +From: Pavel Skripkin +Date: Thu, 19 Aug 2021 12:42:21 +0200 +Subject: media: mxl111sf: change mutex_init() location + +From: Pavel Skripkin + +commit 44870a9e7a3c24acbb3f888b2a7cc22c9bdf7e7f upstream. + +Syzbot reported, that mxl111sf_ctrl_msg() uses uninitialized +mutex. The problem was in wrong mutex_init() location. + +Previous mutex_init(&state->msg_lock) call was in ->init() function, but +dvb_usbv2_init() has this order of calls: + + dvb_usbv2_init() + dvb_usbv2_adapter_init() + dvb_usbv2_adapter_frontend_init() + props->frontend_attach() + + props->init() + +Since mxl111sf_* devices call mxl111sf_ctrl_msg() in ->frontend_attach() +internally we need to initialize state->msg_lock before +frontend_attach(). To achieve it, ->probe() call added to all mxl111sf_* +devices, which will simply initiaize mutex. + +Reported-and-tested-by: syzbot+5ca0bf339f13c4243001@syzkaller.appspotmail.com + +Fixes: 8572211842af ("[media] mxl111sf: convert to new DVB USB") +Signed-off-by: Pavel Skripkin +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/usb/dvb-usb-v2/mxl111sf.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c ++++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c +@@ -931,8 +931,6 @@ static int mxl111sf_init(struct dvb_usb_ + .len = sizeof(eeprom), .buf = eeprom }, + }; + +- mutex_init(&state->msg_lock); +- + ret = get_chip_info(state); + if (mxl_fail(ret)) + pr_err("failed to get chip info during probe"); +@@ -1074,6 +1072,14 @@ static int mxl111sf_get_stream_config_dv + return 0; + } + ++static int mxl111sf_probe(struct dvb_usb_device *dev) ++{ ++ struct mxl111sf_state *state = d_to_priv(dev); ++ ++ mutex_init(&state->msg_lock); ++ return 0; ++} ++ + static struct dvb_usb_device_properties mxl111sf_props_dvbt = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, +@@ -1083,6 +1089,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_dvbt, + .tuner_attach = mxl111sf_attach_tuner, +@@ -1124,6 +1131,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_atsc, + .tuner_attach = mxl111sf_attach_tuner, +@@ -1165,6 +1173,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_mh, + .tuner_attach = mxl111sf_attach_tuner, +@@ -1233,6 +1242,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_atsc_mh, + .tuner_attach = mxl111sf_attach_tuner, +@@ -1311,6 +1321,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_mercury, + .tuner_attach = mxl111sf_attach_tuner, +@@ -1381,6 +1392,7 @@ static struct dvb_usb_device_properties + .generic_bulk_ctrl_endpoint = 0x02, + .generic_bulk_ctrl_endpoint_response = 0x81, + ++ .probe = mxl111sf_probe, + .i2c_algo = &mxl111sf_i2c_algo, + .frontend_attach = mxl111sf_frontend_attach_mercury_mh, + .tuner_attach = mxl111sf_attach_tuner, diff --git a/queue-5.15/mptcp-add-missing-documented-nl-params.patch b/queue-5.15/mptcp-add-missing-documented-nl-params.patch new file mode 100644 index 00000000000..98e9540d9bb --- /dev/null +++ b/queue-5.15/mptcp-add-missing-documented-nl-params.patch @@ -0,0 +1,53 @@ +From 6813b1928758ce64fabbb8ef157f994b7c2235fa Mon Sep 17 00:00:00 2001 +From: Matthieu Baerts +Date: Tue, 14 Dec 2021 15:16:04 -0800 +Subject: mptcp: add missing documented NL params + +From: Matthieu Baerts + +commit 6813b1928758ce64fabbb8ef157f994b7c2235fa upstream. + +'loc_id' and 'rem_id' are set in all events linked to subflows but those +were missing in the events description in the comments. + +Fixes: b911c97c7dc7 ("mptcp: add netlink event support") +Signed-off-by: Matthieu Baerts +Signed-off-by: Mat Martineau +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/mptcp.h | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/include/uapi/linux/mptcp.h ++++ b/include/uapi/linux/mptcp.h +@@ -129,19 +129,21 @@ struct mptcp_info { + * MPTCP_EVENT_REMOVED: token, rem_id + * An address has been lost by the peer. + * +- * MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6, +- * daddr4 | daddr6, sport, dport, backup, +- * if_idx [, error] ++ * MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id, ++ * saddr4 | saddr6, daddr4 | daddr6, sport, ++ * dport, backup, if_idx [, error] + * A new subflow has been established. 'error' should not be set. + * +- * MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6, +- * sport, dport, backup, if_idx [, error] ++ * MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6, ++ * daddr4 | daddr6, sport, dport, backup, if_idx ++ * [, error] + * A subflow has been closed. An error (copy of sk_err) could be set if an + * error has been detected for this subflow. + * +- * MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, +- * sport, dport, backup, if_idx [, error] +- * The priority of a subflow has changed. 'error' should not be set. ++ * MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6, ++ * daddr4 | daddr6, sport, dport, backup, if_idx ++ * [, error] ++ * The priority of a subflow has changed. 'error' should not be set. + */ + enum mptcp_event_type { + MPTCP_EVENT_UNSPEC = 0, diff --git a/queue-5.15/series b/queue-5.15/series index 5ace9449007..e4150c7e982 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -151,4 +151,10 @@ drm-amd-pm-fix-reading-smu-fw-version-from-amdgpu_firmware_info-on-yc.patch revert-can-m_can-remove-support-for-custom-bit-timing.patch can-m_can-make-custom-bittiming-fields-const.patch can-m_can-pci-use-custom-bit-timings-for-elkhart-lake.patch -btrfs-fix-invalid-delayed-ref-after-subvolume-creation-failure.patch +arm-dts-imx6ull-pinfunc-fix-csi_data07__esai_tx0-pad-name.patch +xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch +mptcp-add-missing-documented-nl-params.patch +bpf-x64-factor-out-emission-of-rex-byte-in-more-cases.patch +bpf-fix-extable-address-check.patch +usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch +media-mxl111sf-change-mutex_init-location.patch diff --git a/queue-5.15/usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch b/queue-5.15/usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch new file mode 100644 index 00000000000..178709eed16 --- /dev/null +++ b/queue-5.15/usb-core-make-do_proc_control-and-do_proc_bulk-killable.patch @@ -0,0 +1,304 @@ +From ae8709b296d80c7f45aa1f35c0e7659ad69edce1 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 3 Sep 2021 13:53:12 -0400 +Subject: USB: core: Make do_proc_control() and do_proc_bulk() killable + +From: Alan Stern + +commit ae8709b296d80c7f45aa1f35c0e7659ad69edce1 upstream. + +The USBDEVFS_CONTROL and USBDEVFS_BULK ioctls invoke +usb_start_wait_urb(), which contains an uninterruptible wait with a +user-specified timeout value. If timeout value is very large and the +device being accessed does not respond in a reasonable amount of time, +the kernel will complain about "Task X blocked for more than N +seconds", as found in testing by syzbot: + +INFO: task syz-executor.0:8700 blocked for more than 143 seconds. + Not tainted 5.14.0-rc7-syzkaller #0 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +task:syz-executor.0 state:D stack:23192 pid: 8700 ppid: 8455 flags:0x00004004 +Call Trace: + context_switch kernel/sched/core.c:4681 [inline] + __schedule+0xc07/0x11f0 kernel/sched/core.c:5938 + schedule+0x14b/0x210 kernel/sched/core.c:6017 + schedule_timeout+0x98/0x2f0 kernel/time/timer.c:1857 + do_wait_for_common+0x2da/0x480 kernel/sched/completion.c:85 + __wait_for_common kernel/sched/completion.c:106 [inline] + wait_for_common kernel/sched/completion.c:117 [inline] + wait_for_completion_timeout+0x46/0x60 kernel/sched/completion.c:157 + usb_start_wait_urb+0x167/0x550 drivers/usb/core/message.c:63 + do_proc_bulk+0x978/0x1080 drivers/usb/core/devio.c:1236 + proc_bulk drivers/usb/core/devio.c:1273 [inline] + usbdev_do_ioctl drivers/usb/core/devio.c:2547 [inline] + usbdev_ioctl+0x3441/0x6b10 drivers/usb/core/devio.c:2713 +... + +To fix this problem, this patch replaces usbfs's calls to +usb_control_msg() and usb_bulk_msg() with special-purpose code that +does essentially the same thing (as recommended in the comment for +usb_start_wait_urb()), except that it always uses a killable wait and +it uses GFP_KERNEL rather than GFP_NOIO. + +Reported-and-tested-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com +Suggested-by: Oliver Neukum +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/20210903175312.GA468440@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/devio.c | 144 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 111 insertions(+), 33 deletions(-) + +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -32,6 +32,7 @@ + #include + #include + #include /* for usbcore internals */ ++#include + #include + #include + #include +@@ -1102,14 +1103,55 @@ static int usbdev_release(struct inode * + return 0; + } + ++static void usbfs_blocking_completion(struct urb *urb) ++{ ++ complete((struct completion *) urb->context); ++} ++ ++/* ++ * Much like usb_start_wait_urb, but returns status separately from ++ * actual_length and uses a killable wait. ++ */ ++static int usbfs_start_wait_urb(struct urb *urb, int timeout, ++ unsigned int *actlen) ++{ ++ DECLARE_COMPLETION_ONSTACK(ctx); ++ unsigned long expire; ++ int rc; ++ ++ urb->context = &ctx; ++ urb->complete = usbfs_blocking_completion; ++ *actlen = 0; ++ rc = usb_submit_urb(urb, GFP_KERNEL); ++ if (unlikely(rc)) ++ return rc; ++ ++ expire = (timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT); ++ rc = wait_for_completion_killable_timeout(&ctx, expire); ++ if (rc <= 0) { ++ usb_kill_urb(urb); ++ *actlen = urb->actual_length; ++ if (urb->status != -ENOENT) ++ ; /* Completed before it was killed */ ++ else if (rc < 0) ++ return -EINTR; ++ else ++ return -ETIMEDOUT; ++ } ++ *actlen = urb->actual_length; ++ return urb->status; ++} ++ + static int do_proc_control(struct usb_dev_state *ps, + struct usbdevfs_ctrltransfer *ctrl) + { + struct usb_device *dev = ps->dev; + unsigned int tmo; + unsigned char *tbuf; +- unsigned wLength; ++ unsigned int wLength, actlen; + int i, pipe, ret; ++ struct urb *urb = NULL; ++ struct usb_ctrlrequest *dr = NULL; + + ret = check_ctrlrecip(ps, ctrl->bRequestType, ctrl->bRequest, + ctrl->wIndex); +@@ -1122,51 +1164,63 @@ static int do_proc_control(struct usb_de + sizeof(struct usb_ctrlrequest)); + if (ret) + return ret; ++ ++ ret = -ENOMEM; + tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); +- if (!tbuf) { +- ret = -ENOMEM; ++ if (!tbuf) + goto done; +- } ++ urb = usb_alloc_urb(0, GFP_NOIO); ++ if (!urb) ++ goto done; ++ dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); ++ if (!dr) ++ goto done; ++ ++ dr->bRequestType = ctrl->bRequestType; ++ dr->bRequest = ctrl->bRequest; ++ dr->wValue = cpu_to_le16(ctrl->wValue); ++ dr->wIndex = cpu_to_le16(ctrl->wIndex); ++ dr->wLength = cpu_to_le16(ctrl->wLength); ++ + tmo = ctrl->timeout; + snoop(&dev->dev, "control urb: bRequestType=%02x " + "bRequest=%02x wValue=%04x " + "wIndex=%04x wLength=%04x\n", + ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, + ctrl->wIndex, ctrl->wLength); +- if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) { ++ ++ if ((ctrl->bRequestType & USB_DIR_IN) && wLength) { + pipe = usb_rcvctrlpipe(dev, 0); +- snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); ++ usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, ++ wLength, NULL, NULL); ++ snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, NULL, 0); + + usb_unlock_device(dev); +- i = usb_control_msg(dev, pipe, ctrl->bRequest, +- ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, +- tbuf, ctrl->wLength, tmo); ++ i = usbfs_start_wait_urb(urb, tmo, &actlen); + usb_lock_device(dev); +- snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, +- tbuf, max(i, 0)); +- if ((i > 0) && ctrl->wLength) { +- if (copy_to_user(ctrl->data, tbuf, i)) { ++ snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); ++ if (!i && actlen) { ++ if (copy_to_user(ctrl->data, tbuf, actlen)) { + ret = -EFAULT; +- goto done; ++ goto recv_fault; + } + } + } else { +- if (ctrl->wLength) { +- if (copy_from_user(tbuf, ctrl->data, ctrl->wLength)) { ++ if (wLength) { ++ if (copy_from_user(tbuf, ctrl->data, wLength)) { + ret = -EFAULT; + goto done; + } + } + pipe = usb_sndctrlpipe(dev, 0); +- snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, +- tbuf, ctrl->wLength); ++ usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, ++ wLength, NULL, NULL); ++ snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, tbuf, wLength); + + usb_unlock_device(dev); +- i = usb_control_msg(dev, pipe, ctrl->bRequest, +- ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, +- tbuf, ctrl->wLength, tmo); ++ i = usbfs_start_wait_urb(urb, tmo, &actlen); + usb_lock_device(dev); +- snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0); ++ snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); + } + if (i < 0 && i != -EPIPE) { + dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " +@@ -1174,8 +1228,15 @@ static int do_proc_control(struct usb_de + current->comm, ctrl->bRequestType, ctrl->bRequest, + ctrl->wLength, i); + } +- ret = i; ++ ret = (i < 0 ? i : actlen); ++ ++ recv_fault: ++ /* Linger a bit, prior to the next control message. */ ++ if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) ++ msleep(200); + done: ++ kfree(dr); ++ usb_free_urb(urb); + free_page((unsigned long) tbuf); + usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) + + sizeof(struct usb_ctrlrequest)); +@@ -1195,10 +1256,11 @@ static int do_proc_bulk(struct usb_dev_s + struct usbdevfs_bulktransfer *bulk) + { + struct usb_device *dev = ps->dev; +- unsigned int tmo, len1, pipe; +- int len2; ++ unsigned int tmo, len1, len2, pipe; + unsigned char *tbuf; + int i, ret; ++ struct urb *urb = NULL; ++ struct usb_host_endpoint *ep; + + ret = findintfep(ps->dev, bulk->ep); + if (ret < 0) +@@ -1206,14 +1268,17 @@ static int do_proc_bulk(struct usb_dev_s + ret = checkintf(ps, ret); + if (ret) + return ret; ++ ++ len1 = bulk->len; ++ if (len1 < 0 || len1 >= (INT_MAX - sizeof(struct urb))) ++ return -EINVAL; ++ + if (bulk->ep & USB_DIR_IN) + pipe = usb_rcvbulkpipe(dev, bulk->ep & 0x7f); + else + pipe = usb_sndbulkpipe(dev, bulk->ep & 0x7f); +- if (!usb_maxpacket(dev, pipe, !(bulk->ep & USB_DIR_IN))) +- return -EINVAL; +- len1 = bulk->len; +- if (len1 >= (INT_MAX - sizeof(struct urb))) ++ ep = usb_pipe_endpoint(dev, pipe); ++ if (!ep || !usb_endpoint_maxp(&ep->desc)) + return -EINVAL; + ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); + if (ret) +@@ -1223,17 +1288,29 @@ static int do_proc_bulk(struct usb_dev_s + * len1 can be almost arbitrarily large. Don't WARN if it's + * too big, just fail the request. + */ ++ ret = -ENOMEM; + tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); +- if (!tbuf) { +- ret = -ENOMEM; ++ if (!tbuf) + goto done; ++ urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!urb) ++ goto done; ++ ++ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_INT) { ++ pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); ++ usb_fill_int_urb(urb, dev, pipe, tbuf, len1, ++ NULL, NULL, ep->desc.bInterval); ++ } else { ++ usb_fill_bulk_urb(urb, dev, pipe, tbuf, len1, NULL, NULL); + } ++ + tmo = bulk->timeout; + if (bulk->ep & 0x80) { + snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); + + usb_unlock_device(dev); +- i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); ++ i = usbfs_start_wait_urb(urb, tmo, &len2); + usb_lock_device(dev); + snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2); + +@@ -1253,12 +1330,13 @@ static int do_proc_bulk(struct usb_dev_s + snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); + + usb_unlock_device(dev); +- i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); ++ i = usbfs_start_wait_urb(urb, tmo, &len2); + usb_lock_device(dev); + snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0); + } + ret = (i < 0 ? i : len2); + done: ++ usb_free_urb(urb); + kfree(tbuf); + usbfs_decrease_memory_usage(len1 + sizeof(struct urb)); + return ret; diff --git a/queue-5.15/xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch b/queue-5.15/xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch new file mode 100644 index 00000000000..01aa564abbc --- /dev/null +++ b/queue-5.15/xsk-do-not-sleep-in-poll-when-need_wakeup-set.patch @@ -0,0 +1,52 @@ +From bd0687c18e635b63233dc87f38058cd728802ab4 Mon Sep 17 00:00:00 2001 +From: Magnus Karlsson +Date: Tue, 14 Dec 2021 11:26:07 +0100 +Subject: xsk: Do not sleep in poll() when need_wakeup set + +From: Magnus Karlsson + +commit bd0687c18e635b63233dc87f38058cd728802ab4 upstream. + +Do not sleep in poll() when the need_wakeup flag is set. When this +flag is set, the application needs to explicitly wake up the driver +with a syscall (poll, recvmsg, sendmsg, etc.) to guarantee that Rx +and/or Tx processing will be processed promptly. But the current code +in poll(), sleeps first then wakes up the driver. This means that no +driver processing will occur (baring any interrupts) until the timeout +has expired. + +Fix this by checking the need_wakeup flag first and if set, wake the +driver and return to the application. Only if need_wakeup is not set +should the process sleep if there is a timeout set in the poll() call. + +Fixes: 77cd0d7b3f25 ("xsk: add support for need_wakeup flag in AF_XDP rings") +Reported-by: Keith Wiles +Signed-off-by: Magnus Karlsson +Signed-off-by: Daniel Borkmann +Acked-by: Maciej Fijalkowski +Link: https://lore.kernel.org/bpf/20211214102607.7677-1-magnus.karlsson@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + net/xdp/xsk.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -692,8 +692,6 @@ static __poll_t xsk_poll(struct file *fi + struct xdp_sock *xs = xdp_sk(sk); + struct xsk_buff_pool *pool; + +- sock_poll_wait(file, sock, wait); +- + if (unlikely(!xsk_is_bound(xs))) + return mask; + +@@ -705,6 +703,8 @@ static __poll_t xsk_poll(struct file *fi + else + /* Poll needs to drive Tx also in copy mode */ + __xsk_sendmsg(sk); ++ } else { ++ sock_poll_wait(file, sock, wait); + } + + if (xs->rx && !xskq_prod_is_empty(xs->rx)) -- 2.47.3