From 0eec5af245759a770aaa23ee5dc9c49e6345720e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 21 Apr 2020 16:19:37 +0200 Subject: [PATCH] 5.4-stable patches added patches: arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch ext4-use-non-movable-memory-for-superblock-readahead.patch watchdog-sp805-fix-restart-handler.patch xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch --- ...with-alu64-rsh-arsh-bpf_k-shift-by-0.patch | 63 +++++++++++ ...x-offset-overflow-for-bpf_mem-bpf_dw.patch | 4 +- ...able-memory-for-superblock-readahead.patch | 107 ++++++++++++++++++ queue-5.4/series | 4 + .../watchdog-sp805-fix-restart-handler.patch | 44 +++++++ ...f-boundary-write-in-__xsk_rcv_memcpy.patch | 42 +++++++ 6 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 queue-5.4/arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch create mode 100644 queue-5.4/ext4-use-non-movable-memory-for-superblock-readahead.patch create mode 100644 queue-5.4/watchdog-sp805-fix-restart-handler.patch create mode 100644 queue-5.4/xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch diff --git a/queue-5.4/arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch b/queue-5.4/arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch new file mode 100644 index 00000000000..3cd83416b74 --- /dev/null +++ b/queue-5.4/arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch @@ -0,0 +1,63 @@ +From bb9562cf5c67813034c96afb50bd21130a504441 Mon Sep 17 00:00:00 2001 +From: Luke Nelson +Date: Wed, 8 Apr 2020 18:12:29 +0000 +Subject: arm, bpf: Fix bugs with ALU64 {RSH, ARSH} BPF_K shift by 0 + +From: Luke Nelson + +commit bb9562cf5c67813034c96afb50bd21130a504441 upstream. + +The current arm BPF JIT does not correctly compile RSH or ARSH when the +immediate shift amount is 0. This causes the "rsh64 by 0 imm" and "arsh64 +by 0 imm" BPF selftests to hang the kernel by reaching an instruction +the verifier determines to be unreachable. + +The root cause is in how immediate right shifts are encoded on arm. +For LSR and ASR (logical and arithmetic right shift), a bit-pattern +of 00000 in the immediate encodes a shift amount of 32. When the BPF +immediate is 0, the generated code shifts by 32 instead of the expected +behavior (a no-op). + +This patch fixes the bugs by adding an additional check if the BPF +immediate is 0. After the change, the above mentioned BPF selftests pass. + +Fixes: 39c13c204bb11 ("arm: eBPF JIT compiler") +Co-developed-by: Xi Wang +Signed-off-by: Xi Wang +Signed-off-by: Luke Nelson +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20200408181229.10909-1-luke.r.nels@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/net/bpf_jit_32.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/arch/arm/net/bpf_jit_32.c ++++ b/arch/arm/net/bpf_jit_32.c +@@ -929,7 +929,11 @@ static inline void emit_a32_rsh_i64(cons + rd = arm_bpf_get_reg64(dst, tmp, ctx); + + /* Do LSR operation */ +- if (val < 32) { ++ if (val == 0) { ++ /* An immediate value of 0 encodes a shift amount of 32 ++ * for LSR. To shift by 0, don't do anything. ++ */ ++ } else if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx); +@@ -955,7 +959,11 @@ static inline void emit_a32_arsh_i64(con + rd = arm_bpf_get_reg64(dst, tmp, ctx); + + /* Do ARSH operation */ +- if (val < 32) { ++ if (val == 0) { ++ /* An immediate value of 0 encodes a shift amount of 32 ++ * for ASR. To shift by 0, don't do anything. ++ */ ++ } else if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx); diff --git a/queue-5.4/arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch b/queue-5.4/arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch index 1c0abd0ef93..78135979f89 100644 --- a/queue-5.4/arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch +++ b/queue-5.4/arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch @@ -42,7 +42,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c -@@ -992,21 +992,35 @@ static inline void emit_a32_mul_r64(cons +@@ -1000,21 +1000,35 @@ static inline void emit_a32_mul_r64(cons arm_bpf_put_reg32(dst_hi, rd[0], ctx); } @@ -86,7 +86,7 @@ Signed-off-by: Greg Kroah-Hartman emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); rd = tmp[0]; -@@ -1035,18 +1049,12 @@ static inline void emit_str_r(const s8 d +@@ -1043,18 +1057,12 @@ static inline void emit_str_r(const s8 d /* dst = *(size*)(src + off) */ static inline void emit_ldx_r(const s8 dst[], const s8 src, diff --git a/queue-5.4/ext4-use-non-movable-memory-for-superblock-readahead.patch b/queue-5.4/ext4-use-non-movable-memory-for-superblock-readahead.patch new file mode 100644 index 00000000000..90c8213aef0 --- /dev/null +++ b/queue-5.4/ext4-use-non-movable-memory-for-superblock-readahead.patch @@ -0,0 +1,107 @@ +From d87f639258a6a5980183f11876c884931ad93da2 Mon Sep 17 00:00:00 2001 +From: Roman Gushchin +Date: Fri, 28 Feb 2020 16:14:11 -0800 +Subject: ext4: use non-movable memory for superblock readahead + +From: Roman Gushchin + +commit d87f639258a6a5980183f11876c884931ad93da2 upstream. + +Since commit a8ac900b8163 ("ext4: use non-movable memory for the +superblock") buffers for ext4 superblock were allocated using +the sb_bread_unmovable() helper which allocated buffer heads +out of non-movable memory blocks. It was necessarily to not block +page migrations and do not cause cma allocation failures. + +However commit 85c8f176a611 ("ext4: preload block group descriptors") +broke this by introducing pre-reading of the ext4 superblock. +The problem is that __breadahead() is using __getblk() underneath, +which allocates buffer heads out of movable memory. + +It resulted in page migration failures I've seen on a machine +with an ext4 partition and a preallocated cma area. + +Fix this by introducing sb_breadahead_unmovable() and +__breadahead_gfp() helpers which use non-movable memory for buffer +head allocations and use them for the ext4 superblock readahead. + +Reviewed-by: Andreas Dilger +Fixes: 85c8f176a611 ("ext4: preload block group descriptors") +Signed-off-by: Roman Gushchin +Link: https://lore.kernel.org/r/20200229001411.128010-1-guro@fb.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/buffer.c | 11 +++++++++++ + fs/ext4/inode.c | 2 +- + fs/ext4/super.c | 2 +- + include/linux/buffer_head.h | 8 ++++++++ + 4 files changed, 21 insertions(+), 2 deletions(-) + +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -1337,6 +1337,17 @@ void __breadahead(struct block_device *b + } + EXPORT_SYMBOL(__breadahead); + ++void __breadahead_gfp(struct block_device *bdev, sector_t block, unsigned size, ++ gfp_t gfp) ++{ ++ struct buffer_head *bh = __getblk_gfp(bdev, block, size, gfp); ++ if (likely(bh)) { ++ ll_rw_block(REQ_OP_READ, REQ_RAHEAD, 1, &bh); ++ brelse(bh); ++ } ++} ++EXPORT_SYMBOL(__breadahead_gfp); ++ + /** + * __bread_gfp() - reads a specified block and returns the bh + * @bdev: the block_device to read from +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4680,7 +4680,7 @@ make_io: + if (end > table) + end = table; + while (b <= end) +- sb_breadahead(sb, b++); ++ sb_breadahead_unmovable(sb, b++); + } + + /* +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4283,7 +4283,7 @@ static int ext4_fill_super(struct super_ + /* Pre-read the descriptors into the buffer cache */ + for (i = 0; i < db_count; i++) { + block = descriptor_loc(sb, logical_sb_block, i); +- sb_breadahead(sb, block); ++ sb_breadahead_unmovable(sb, block); + } + + for (i = 0; i < db_count; i++) { +--- a/include/linux/buffer_head.h ++++ b/include/linux/buffer_head.h +@@ -189,6 +189,8 @@ struct buffer_head *__getblk_gfp(struct + void __brelse(struct buffer_head *); + void __bforget(struct buffer_head *); + void __breadahead(struct block_device *, sector_t block, unsigned int size); ++void __breadahead_gfp(struct block_device *, sector_t block, unsigned int size, ++ gfp_t gfp); + struct buffer_head *__bread_gfp(struct block_device *, + sector_t block, unsigned size, gfp_t gfp); + void invalidate_bh_lrus(void); +@@ -319,6 +321,12 @@ sb_breadahead(struct super_block *sb, se + __breadahead(sb->s_bdev, block, sb->s_blocksize); + } + ++static inline void ++sb_breadahead_unmovable(struct super_block *sb, sector_t block) ++{ ++ __breadahead_gfp(sb->s_bdev, block, sb->s_blocksize, 0); ++} ++ + static inline struct buffer_head * + sb_getblk(struct super_block *sb, sector_t block) + { diff --git a/queue-5.4/series b/queue-5.4/series index 132426f5008..99f57d66ff3 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -1,3 +1,7 @@ +ext4-use-non-movable-memory-for-superblock-readahead.patch +watchdog-sp805-fix-restart-handler.patch +xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch +arm-bpf-fix-bugs-with-alu64-rsh-arsh-bpf_k-shift-by-0.patch arm-bpf-fix-offset-overflow-for-bpf_mem-bpf_dw.patch objtool-fix-switch-table-detection-in-.text.unlikely.patch scsi-sg-add-sg_remove_request-in-sg_common_write.patch diff --git a/queue-5.4/watchdog-sp805-fix-restart-handler.patch b/queue-5.4/watchdog-sp805-fix-restart-handler.patch new file mode 100644 index 00000000000..6fde3586c87 --- /dev/null +++ b/queue-5.4/watchdog-sp805-fix-restart-handler.patch @@ -0,0 +1,44 @@ +From ea104a9e4d3e9ebc26fb78dac35585b142ee288b Mon Sep 17 00:00:00 2001 +From: Michael Walle +Date: Fri, 27 Mar 2020 17:24:50 +0100 +Subject: watchdog: sp805: fix restart handler + +From: Michael Walle + +commit ea104a9e4d3e9ebc26fb78dac35585b142ee288b upstream. + +The restart handler is missing two things, first, the registers +has to be unlocked and second there is no synchronization for the +write_relaxed() calls. + +This was tested on a custom board with the NXP LS1028A SoC. + +Fixes: 6c5c0d48b686c ("watchdog: sp805: add restart handler") +Signed-off-by: Michael Walle +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20200327162450.28506-1-michael@walle.cc +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/watchdog/sp805_wdt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/watchdog/sp805_wdt.c ++++ b/drivers/watchdog/sp805_wdt.c +@@ -137,10 +137,14 @@ wdt_restart(struct watchdog_device *wdd, + { + struct sp805_wdt *wdt = watchdog_get_drvdata(wdd); + ++ writel_relaxed(UNLOCK, wdt->base + WDTLOCK); + writel_relaxed(0, wdt->base + WDTCONTROL); + writel_relaxed(0, wdt->base + WDTLOAD); + writel_relaxed(INT_ENABLE | RESET_ENABLE, wdt->base + WDTCONTROL); + ++ /* Flush posted writes. */ ++ readl_relaxed(wdt->base + WDTLOCK); ++ + return 0; + } + diff --git a/queue-5.4/xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch b/queue-5.4/xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch new file mode 100644 index 00000000000..411edb595ce --- /dev/null +++ b/queue-5.4/xsk-fix-out-of-boundary-write-in-__xsk_rcv_memcpy.patch @@ -0,0 +1,42 @@ +From db5c97f02373917efe2c218ebf8e3d8b19e343b6 Mon Sep 17 00:00:00 2001 +From: Li RongQing +Date: Thu, 2 Apr 2020 15:52:10 +0800 +Subject: xsk: Fix out of boundary write in __xsk_rcv_memcpy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Li RongQing + +commit db5c97f02373917efe2c218ebf8e3d8b19e343b6 upstream. + +first_len is the remainder of the first page we're copying. +If this size is larger, then out of page boundary write will +otherwise happen. + +Fixes: c05cd3645814 ("xsk: add support to allow unaligned chunk placement") +Signed-off-by: Li RongQing +Signed-off-by: Daniel Borkmann +Acked-by: Jonathan Lemon +Acked-by: Björn Töpel +Link: https://lore.kernel.org/bpf/1585813930-19712-1-git-send-email-lirongqing@baidu.com +Signed-off-by: Greg Kroah-Hartman + +--- + net/xdp/xsk.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/net/xdp/xsk.c ++++ b/net/xdp/xsk.c +@@ -129,8 +129,9 @@ static void __xsk_rcv_memcpy(struct xdp_ + u64 page_start = addr & ~(PAGE_SIZE - 1); + u64 first_len = PAGE_SIZE - (addr - page_start); + +- memcpy(to_buf, from_buf, first_len + metalen); +- memcpy(next_pg_addr, from_buf + first_len, len - first_len); ++ memcpy(to_buf, from_buf, first_len); ++ memcpy(next_pg_addr, from_buf + first_len, ++ len + metalen - first_len); + + return; + } -- 2.47.3