From: Greg Kroah-Hartman Date: Tue, 11 Apr 2023 14:01:35 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.15.107~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fd4fd64eb5f1351441e04a6f146914e7fa609e60;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: drm-nouveau-disp-support-more-modes-by-checking-with-lower-bpc.patch drm-panfrost-fix-the-panfrost_mmu_map_fault_addr-error-path.patch mm-swap-fix-swap_info_struct-race-between-swapoff-and-get_swap_pages.patch ring-buffer-fix-race-while-reader-and-writer-are-on-the-same-page.patch --- diff --git a/queue-5.10/drm-nouveau-disp-support-more-modes-by-checking-with-lower-bpc.patch b/queue-5.10/drm-nouveau-disp-support-more-modes-by-checking-with-lower-bpc.patch new file mode 100644 index 00000000000..274afbcdeb4 --- /dev/null +++ b/queue-5.10/drm-nouveau-disp-support-more-modes-by-checking-with-lower-bpc.patch @@ -0,0 +1,96 @@ +From 7f67aa097e875c87fba024e850cf405342300059 Mon Sep 17 00:00:00 2001 +From: Karol Herbst +Date: Fri, 31 Mar 2023 00:39:38 +0200 +Subject: drm/nouveau/disp: Support more modes by checking with lower bpc + +From: Karol Herbst + +commit 7f67aa097e875c87fba024e850cf405342300059 upstream. + +This allows us to advertise more modes especially on HDR displays. + +Fixes using 4K@60 modes on my TV and main display both using a HDMI to DP +adapter. Also fixes similar issues for users running into this. + +Cc: stable@vger.kernel.org # 5.10+ +Signed-off-by: Karol Herbst +Reviewed-by: Lyude Paul +Link: https://patchwork.freedesktop.org/patch/msgid/20230330223938.4025569-1-kherbst@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/nouveau/dispnv50/disp.c | 32 ++++++++++++++++++++++++++++++++ + drivers/gpu/drm/nouveau/nouveau_dp.c | 8 +++++--- + 2 files changed, 37 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c ++++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c +@@ -396,6 +396,35 @@ nv50_outp_atomic_check_view(struct drm_e + return 0; + } + ++static void ++nv50_outp_atomic_fix_depth(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state) ++{ ++ struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); ++ struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); ++ struct drm_display_mode *mode = &asyh->state.adjusted_mode; ++ unsigned int max_rate, mode_rate; ++ ++ switch (nv_encoder->dcb->type) { ++ case DCB_OUTPUT_DP: ++ max_rate = nv_encoder->dp.link_nr * nv_encoder->dp.link_bw; ++ ++ /* we don't support more than 10 anyway */ ++ asyh->or.bpc = min_t(u8, asyh->or.bpc, 10); ++ ++ /* reduce the bpc until it works out */ ++ while (asyh->or.bpc > 6) { ++ mode_rate = DIV_ROUND_UP(mode->clock * asyh->or.bpc * 3, 8); ++ if (mode_rate <= max_rate) ++ break; ++ ++ asyh->or.bpc -= 2; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ + static int + nv50_outp_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, +@@ -414,6 +443,9 @@ nv50_outp_atomic_check(struct drm_encode + if (crtc_state->mode_changed || crtc_state->connectors_changed) + asyh->or.bpc = connector->display_info.bpc; + ++ /* We might have to reduce the bpc */ ++ nv50_outp_atomic_fix_depth(encoder, crtc_state); ++ + return 0; + } + +--- a/drivers/gpu/drm/nouveau/nouveau_dp.c ++++ b/drivers/gpu/drm/nouveau/nouveau_dp.c +@@ -220,8 +220,6 @@ void nouveau_dp_irq(struct nouveau_drm * + } + + /* TODO: +- * - Use the minimum possible BPC here, once we add support for the max bpc +- * property. + * - Validate against the DP caps advertised by the GPU (we don't check these + * yet) + */ +@@ -233,7 +231,11 @@ nv50_dp_mode_valid(struct drm_connector + { + const unsigned int min_clock = 25000; + unsigned int max_rate, mode_rate, ds_max_dotclock, clock = mode->clock; +- const u8 bpp = connector->display_info.bpc * 3; ++ /* Check with the minmum bpc always, so we can advertise better modes. ++ * In particlar not doing this causes modes to be dropped on HDR ++ * displays as we might check with a bpc of 16 even. ++ */ ++ const u8 bpp = 6 * 3; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE && !outp->caps.dp_interlace) + return MODE_NO_INTERLACE; diff --git a/queue-5.10/drm-panfrost-fix-the-panfrost_mmu_map_fault_addr-error-path.patch b/queue-5.10/drm-panfrost-fix-the-panfrost_mmu_map_fault_addr-error-path.patch new file mode 100644 index 00000000000..0d6e35d71e5 --- /dev/null +++ b/queue-5.10/drm-panfrost-fix-the-panfrost_mmu_map_fault_addr-error-path.patch @@ -0,0 +1,33 @@ +From 764a2ab9eb56e1200083e771aab16186836edf1d Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Fri, 21 May 2021 11:38:11 +0200 +Subject: drm/panfrost: Fix the panfrost_mmu_map_fault_addr() error path + +From: Boris Brezillon + +commit 764a2ab9eb56e1200083e771aab16186836edf1d upstream. + +Make sure all bo->base.pages entries are either NULL or pointing to a +valid page before calling drm_gem_shmem_put_pages(). + +Reported-by: Tomeu Vizoso +Cc: +Fixes: 187d2929206e ("drm/panfrost: Add support for GPU heap allocations") +Signed-off-by: Boris Brezillon +Reviewed-by: Steven Price +Link: https://patchwork.freedesktop.org/patch/msgid/20210521093811.1018992-1-boris.brezillon@collabora.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/panfrost/panfrost_mmu.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -458,6 +458,7 @@ static int panfrost_mmu_map_fault_addr(s + if (IS_ERR(pages[i])) { + mutex_unlock(&bo->base.pages_lock); + ret = PTR_ERR(pages[i]); ++ pages[i] = NULL; + goto err_pages; + } + } diff --git a/queue-5.10/mm-swap-fix-swap_info_struct-race-between-swapoff-and-get_swap_pages.patch b/queue-5.10/mm-swap-fix-swap_info_struct-race-between-swapoff-and-get_swap_pages.patch new file mode 100644 index 00000000000..95e5731ad48 --- /dev/null +++ b/queue-5.10/mm-swap-fix-swap_info_struct-race-between-swapoff-and-get_swap_pages.patch @@ -0,0 +1,119 @@ +From 6fe7d6b992113719e96744d974212df3fcddc76c Mon Sep 17 00:00:00 2001 +From: Rongwei Wang +Date: Tue, 4 Apr 2023 23:47:16 +0800 +Subject: mm/swap: fix swap_info_struct race between swapoff and get_swap_pages() + +From: Rongwei Wang + +commit 6fe7d6b992113719e96744d974212df3fcddc76c upstream. + +The si->lock must be held when deleting the si from the available list. +Otherwise, another thread can re-add the si to the available list, which +can lead to memory corruption. The only place we have found where this +happens is in the swapoff path. This case can be described as below: + +core 0 core 1 +swapoff + +del_from_avail_list(si) waiting + +try lock si->lock acquire swap_avail_lock + and re-add si into + swap_avail_head + +acquire si->lock but missing si already being added again, and continuing +to clear SWP_WRITEOK, etc. + +It can be easily found that a massive warning messages can be triggered +inside get_swap_pages() by some special cases, for example, we call +madvise(MADV_PAGEOUT) on blocks of touched memory concurrently, meanwhile, +run much swapon-swapoff operations (e.g. stress-ng-swap). + +However, in the worst case, panic can be caused by the above scene. In +swapoff(), the memory used by si could be kept in swap_info[] after +turning off a swap. This means memory corruption will not be caused +immediately until allocated and reset for a new swap in the swapon path. +A panic message caused: (with CONFIG_PLIST_DEBUG enabled) + +------------[ cut here ]------------ +top: 00000000e58a3003, n: 0000000013e75cda, p: 000000008cd4451a +prev: 0000000035b1e58a, n: 000000008cd4451a, p: 000000002150ee8d +next: 000000008cd4451a, n: 000000008cd4451a, p: 000000008cd4451a +WARNING: CPU: 21 PID: 1843 at lib/plist.c:60 plist_check_prev_next_node+0x50/0x70 +Modules linked in: rfkill(E) crct10dif_ce(E)... +CPU: 21 PID: 1843 Comm: stress-ng Kdump: ... 5.10.134+ +Hardware name: Alibaba Cloud ECS, BIOS 0.0.0 02/06/2015 +pstate: 60400005 (nZCv daif +PAN -UAO -TCO BTYPE=--) +pc : plist_check_prev_next_node+0x50/0x70 +lr : plist_check_prev_next_node+0x50/0x70 +sp : ffff0018009d3c30 +x29: ffff0018009d3c40 x28: ffff800011b32a98 +x27: 0000000000000000 x26: ffff001803908000 +x25: ffff8000128ea088 x24: ffff800011b32a48 +x23: 0000000000000028 x22: ffff001800875c00 +x21: ffff800010f9e520 x20: ffff001800875c00 +x19: ffff001800fdc6e0 x18: 0000000000000030 +x17: 0000000000000000 x16: 0000000000000000 +x15: 0736076307640766 x14: 0730073007380731 +x13: 0736076307640766 x12: 0730073007380731 +x11: 000000000004058d x10: 0000000085a85b76 +x9 : ffff8000101436e4 x8 : ffff800011c8ce08 +x7 : 0000000000000000 x6 : 0000000000000001 +x5 : ffff0017df9ed338 x4 : 0000000000000001 +x3 : ffff8017ce62a000 x2 : ffff0017df9ed340 +x1 : 0000000000000000 x0 : 0000000000000000 +Call trace: + plist_check_prev_next_node+0x50/0x70 + plist_check_head+0x80/0xf0 + plist_add+0x28/0x140 + add_to_avail_list+0x9c/0xf0 + _enable_swap_info+0x78/0xb4 + __do_sys_swapon+0x918/0xa10 + __arm64_sys_swapon+0x20/0x30 + el0_svc_common+0x8c/0x220 + do_el0_svc+0x2c/0x90 + el0_svc+0x1c/0x30 + el0_sync_handler+0xa8/0xb0 + el0_sync+0x148/0x180 +irq event stamp: 2082270 + +Now, si->lock locked before calling 'del_from_avail_list()' to make sure +other thread see the si had been deleted and SWP_WRITEOK cleared together, +will not reinsert again. + +This problem exists in versions after stable 5.10.y. + +Link: https://lkml.kernel.org/r/20230404154716.23058-1-rongwei.wang@linux.alibaba.com +Fixes: a2468cc9bfdff ("swap: choose swap device according to numa node") +Tested-by: Yongchen Yin +Signed-off-by: Rongwei Wang +Cc: Bagas Sanjaya +Cc: Matthew Wilcox (Oracle) +Cc: Aaron Lu +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/swapfile.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -666,6 +666,7 @@ static void __del_from_avail_list(struct + { + int nid; + ++ assert_spin_locked(&p->lock); + for_each_node(nid) + plist_del(&p->avail_lists[nid], &swap_avail_heads[nid]); + } +@@ -2611,8 +2612,8 @@ SYSCALL_DEFINE1(swapoff, const char __us + spin_unlock(&swap_lock); + goto out_dput; + } +- del_from_avail_list(p); + spin_lock(&p->lock); ++ del_from_avail_list(p); + if (p->prio < 0) { + struct swap_info_struct *si = p; + int nid; diff --git a/queue-5.10/ring-buffer-fix-race-while-reader-and-writer-are-on-the-same-page.patch b/queue-5.10/ring-buffer-fix-race-while-reader-and-writer-are-on-the-same-page.patch new file mode 100644 index 00000000000..48eb3c71870 --- /dev/null +++ b/queue-5.10/ring-buffer-fix-race-while-reader-and-writer-are-on-the-same-page.patch @@ -0,0 +1,103 @@ +From 6455b6163d8c680366663cdb8c679514d55fc30c Mon Sep 17 00:00:00 2001 +From: Zheng Yejian +Date: Sat, 25 Mar 2023 10:12:47 +0800 +Subject: ring-buffer: Fix race while reader and writer are on the same page + +From: Zheng Yejian + +commit 6455b6163d8c680366663cdb8c679514d55fc30c upstream. + +When user reads file 'trace_pipe', kernel keeps printing following logs +that warn at "cpu_buffer->reader_page->read > rb_page_size(reader)" in +rb_get_reader_page(). It just looks like there's an infinite loop in +tracing_read_pipe(). This problem occurs several times on arm64 platform +when testing v5.10 and below. + + Call trace: + rb_get_reader_page+0x248/0x1300 + rb_buffer_peek+0x34/0x160 + ring_buffer_peek+0xbc/0x224 + peek_next_entry+0x98/0xbc + __find_next_entry+0xc4/0x1c0 + trace_find_next_entry_inc+0x30/0x94 + tracing_read_pipe+0x198/0x304 + vfs_read+0xb4/0x1e0 + ksys_read+0x74/0x100 + __arm64_sys_read+0x24/0x30 + el0_svc_common.constprop.0+0x7c/0x1bc + do_el0_svc+0x2c/0x94 + el0_svc+0x20/0x30 + el0_sync_handler+0xb0/0xb4 + el0_sync+0x160/0x180 + +Then I dump the vmcore and look into the problematic per_cpu ring_buffer, +I found that tail_page/commit_page/reader_page are on the same page while +reader_page->read is obviously abnormal: + tail_page == commit_page == reader_page == { + .write = 0x100d20, + .read = 0x8f9f4805, // Far greater than 0xd20, obviously abnormal!!! + .entries = 0x10004c, + .real_end = 0x0, + .page = { + .time_stamp = 0x857257416af0, + .commit = 0xd20, // This page hasn't been full filled. + // .data[0...0xd20] seems normal. + } + } + +The root cause is most likely the race that reader and writer are on the +same page while reader saw an event that not fully committed by writer. + +To fix this, add memory barriers to make sure the reader can see the +content of what is committed. Since commit a0fcaaed0c46 ("ring-buffer: Fix +race between reset page and reading page") has added the read barrier in +rb_get_reader_page(), here we just need to add the write barrier. + +Link: https://lore.kernel.org/linux-trace-kernel/20230325021247.2923907-1-zhengyejian1@huawei.com + +Cc: stable@vger.kernel.org +Fixes: 77ae365eca89 ("ring-buffer: make lockless") +Suggested-by: Steven Rostedt (Google) +Signed-off-by: Zheng Yejian +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/ring_buffer.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -2962,6 +2962,10 @@ rb_set_commit_to_write(struct ring_buffe + if (RB_WARN_ON(cpu_buffer, + rb_is_reader_page(cpu_buffer->tail_page))) + return; ++ /* ++ * No need for a memory barrier here, as the update ++ * of the tail_page did it for this page. ++ */ + local_set(&cpu_buffer->commit_page->page->commit, + rb_page_write(cpu_buffer->commit_page)); + rb_inc_page(cpu_buffer, &cpu_buffer->commit_page); +@@ -2971,6 +2975,8 @@ rb_set_commit_to_write(struct ring_buffe + while (rb_commit_index(cpu_buffer) != + rb_page_write(cpu_buffer->commit_page)) { + ++ /* Make sure the readers see the content of what is committed. */ ++ smp_wmb(); + local_set(&cpu_buffer->commit_page->page->commit, + rb_page_write(cpu_buffer->commit_page)); + RB_WARN_ON(cpu_buffer, +@@ -4390,7 +4396,12 @@ rb_get_reader_page(struct ring_buffer_pe + + /* + * Make sure we see any padding after the write update +- * (see rb_reset_tail()) ++ * (see rb_reset_tail()). ++ * ++ * In addition, a writer may be writing on the reader page ++ * if the page has not been fully filled, so the read barrier ++ * is also needed to make sure we see the content of what is ++ * committed by the writer (see rb_set_commit_to_write()). + */ + smp_rmb(); + diff --git a/queue-5.10/series b/queue-5.10/series index 28c1885dd6f..5585418cab3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -41,3 +41,7 @@ can-j1939-j1939_tp_tx_dat_new-fix-out-of-bounds-memory-access.patch can-isotp-isotp_ops-fix-poll-to-not-report-false-epollout-events.patch tracing-free-error-logs-of-tracing-instances.patch asoc-hdac_hdmi-use-set_stream-instead-of-set_tdm_slots.patch +drm-panfrost-fix-the-panfrost_mmu_map_fault_addr-error-path.patch +drm-nouveau-disp-support-more-modes-by-checking-with-lower-bpc.patch +ring-buffer-fix-race-while-reader-and-writer-are-on-the-same-page.patch +mm-swap-fix-swap_info_struct-race-between-swapoff-and-get_swap_pages.patch