]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jul 2025 08:55:27 +0000 (10:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jul 2025 08:55:27 +0000 (10:55 +0200)
added patches:
erofs-address-d-cache-aliasing.patch
mm-khugepaged-fix-call-hpage_collapse_scan_file-for-anonymous-vma.patch

queue-6.6/erofs-address-d-cache-aliasing.patch [new file with mode: 0644]
queue-6.6/mm-khugepaged-fix-call-hpage_collapse_scan_file-for-anonymous-vma.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-6.6/erofs-address-d-cache-aliasing.patch b/queue-6.6/erofs-address-d-cache-aliasing.patch
new file mode 100644 (file)
index 0000000..60ce60d
--- /dev/null
@@ -0,0 +1,133 @@
+From 27917e8194f91dffd8b4825350c63cb68e98ce58 Mon Sep 17 00:00:00 2001
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+Date: Wed, 9 Jul 2025 11:46:14 +0800
+Subject: erofs: address D-cache aliasing
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+commit 27917e8194f91dffd8b4825350c63cb68e98ce58 upstream.
+
+Flush the D-cache before unlocking folios for compressed inodes, as
+they are dirtied during decompression.
+
+Avoid calling flush_dcache_folio() on every CPU write, since it's more
+like playing whack-a-mole without real benefit.
+
+It has no impact on x86 and arm64/risc-v: on x86, flush_dcache_folio()
+is a no-op, and on arm64/risc-v, PG_dcache_clean (PG_arch_1) is clear
+for new page cache folios.  However, certain ARM boards are affected,
+as reported.
+
+Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support")
+Closes: https://lore.kernel.org/r/c1e51e16-6cc6-49d0-a63e-4e9ff6c4dd53@pengutronix.de
+Closes: https://lore.kernel.org/r/38d43fae-1182-4155-9c5b-ffc7382d9917@siemens.com
+Tested-by: Jan Kiszka <jan.kiszka@siemens.com>
+Tested-by: Stefan Kerkmann <s.kerkmann@pengutronix.de>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20250709034614.2780117-2-hsiangkao@linux.alibaba.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/decompressor.c |    6 ++----
+ fs/erofs/zdata.c        |   32 +++++++++++++++++++-------------
+ 2 files changed, 21 insertions(+), 17 deletions(-)
+
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -342,14 +342,12 @@ static int z_erofs_transform_plain(struc
+       if (outpages > inpages) {
+               DBG_BUGON(!rq->out[outpages - 1]);
+-              if (rq->out[outpages - 1] != rq->in[inpages - 1]) {
++              if (rq->out[outpages - 1] != rq->in[inpages - 1])
+                       memcpy_to_page(rq->out[outpages - 1], 0, src +
+                                       (interlaced_offset ? 0 : righthalf),
+                                      lefthalf);
+-              } else if (!interlaced_offset) {
++              else if (!interlaced_offset)
+                       memmove(src, src + righthalf, lefthalf);
+-                      flush_dcache_page(rq->in[inpages - 1]);
+-              }
+       }
+       kunmap_local(src);
+       return 0;
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -122,9 +122,11 @@ static inline unsigned int z_erofs_pclus
+ /*
+  * bit 30: I/O error occurred on this page
++ * bit 29: CPU has dirty data in D-cache (needs aliasing handling);
+  * bit 0 - 29: remaining parts to complete this page
+  */
+-#define Z_EROFS_PAGE_EIO                      (1 << 30)
++#define Z_EROFS_ONLINEPAGE_EIO                30
++#define Z_EROFS_ONLINEPAGE_DIRTY      29
+ static inline void z_erofs_onlinepage_init(struct page *page)
+ {
+@@ -143,7 +145,7 @@ static inline void z_erofs_onlinepage_sp
+       atomic_inc((atomic_t *)&page->private);
+ }
+-static void z_erofs_onlinepage_endio(struct page *page, int err)
++static void z_erofs_onlinepage_end(struct page *page, int err, bool dirty)
+ {
+       int orig, v;
+@@ -151,16 +153,20 @@ static void z_erofs_onlinepage_endio(str
+       do {
+               orig = atomic_read((atomic_t *)&page->private);
+-              v = (orig - 1) | (err ? Z_EROFS_PAGE_EIO : 0);
++              DBG_BUGON(orig <= 0);
++              v = dirty << Z_EROFS_ONLINEPAGE_DIRTY;
++              v |= (orig - 1) | (!!err << Z_EROFS_ONLINEPAGE_EIO);
+       } while (atomic_cmpxchg((atomic_t *)&page->private, orig, v) != orig);
+-      if (!(v & ~Z_EROFS_PAGE_EIO)) {
+-              set_page_private(page, 0);
+-              ClearPagePrivate(page);
+-              if (!(v & Z_EROFS_PAGE_EIO))
+-                      SetPageUptodate(page);
+-              unlock_page(page);
+-      }
++      if (v & (BIT(Z_EROFS_ONLINEPAGE_DIRTY) - 1))
++              return;
++      set_page_private(page, 0);
++      ClearPagePrivate(page);
++      if (v & BIT(Z_EROFS_ONLINEPAGE_DIRTY))
++              flush_dcache_page(page);
++      if (!(v & BIT(Z_EROFS_ONLINEPAGE_EIO)))
++              SetPageUptodate(page);
++      unlock_page(page);
+ }
+ #define Z_EROFS_ONSTACK_PAGES         32
+@@ -1060,7 +1066,7 @@ next_part:
+               goto repeat;
+ out:
+-      z_erofs_onlinepage_endio(page, err);
++      z_erofs_onlinepage_end(page, err, false);
+       return err;
+ }
+@@ -1163,7 +1169,7 @@ static void z_erofs_fill_other_copies(st
+                       cur += len;
+               }
+               kunmap_local(dst);
+-              z_erofs_onlinepage_endio(bvi->bvec.page, err);
++              z_erofs_onlinepage_end(bvi->bvec.page, err, true);
+               list_del(p);
+               kfree(bvi);
+       }
+@@ -1333,7 +1339,7 @@ out:
+               /* recycle all individual short-lived pages */
+               if (z_erofs_put_shortlivedpage(be->pagepool, page))
+                       continue;
+-              z_erofs_onlinepage_endio(page, err);
++              z_erofs_onlinepage_end(page, err, true);
+       }
+       if (be->decompressed_pages != be->onstack_pages)
diff --git a/queue-6.6/mm-khugepaged-fix-call-hpage_collapse_scan_file-for-anonymous-vma.patch b/queue-6.6/mm-khugepaged-fix-call-hpage_collapse_scan_file-for-anonymous-vma.patch
new file mode 100644 (file)
index 0000000..50de9b7
--- /dev/null
@@ -0,0 +1,93 @@
+From f1897f2f08b28ae59476d8b73374b08f856973af Mon Sep 17 00:00:00 2001
+From: Liu Shixin <liushixin2@huawei.com>
+Date: Sat, 11 Jan 2025 11:45:11 +0800
+Subject: mm: khugepaged: fix call hpage_collapse_scan_file() for anonymous vma
+
+From: Liu Shixin <liushixin2@huawei.com>
+
+commit f1897f2f08b28ae59476d8b73374b08f856973af upstream.
+
+syzkaller reported such a BUG_ON():
+
+ ------------[ cut here ]------------
+ kernel BUG at mm/khugepaged.c:1835!
+ Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
+ ...
+ CPU: 6 UID: 0 PID: 8009 Comm: syz.15.106 Kdump: loaded Tainted: G        W          6.13.0-rc6 #22
+ Tainted: [W]=WARN
+ Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
+ pstate: 00400005 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+ pc : collapse_file+0xa44/0x1400
+ lr : collapse_file+0x88/0x1400
+ sp : ffff80008afe3a60
+ ...
+ Call trace:
+  collapse_file+0xa44/0x1400 (P)
+  hpage_collapse_scan_file+0x278/0x400
+  madvise_collapse+0x1bc/0x678
+  madvise_vma_behavior+0x32c/0x448
+  madvise_walk_vmas.constprop.0+0xbc/0x140
+  do_madvise.part.0+0xdc/0x2c8
+  __arm64_sys_madvise+0x68/0x88
+  invoke_syscall+0x50/0x120
+  el0_svc_common.constprop.0+0xc8/0xf0
+  do_el0_svc+0x24/0x38
+  el0_svc+0x34/0x128
+  el0t_64_sync_handler+0xc8/0xd0
+  el0t_64_sync+0x190/0x198
+
+This indicates that the pgoff is unaligned.  After analysis, I confirm the
+vma is mapped to /dev/zero.  Such a vma certainly has vm_file, but it is
+set to anonymous by mmap_zero().  So even if it's mmapped by 2m-unaligned,
+it can pass the check in thp_vma_allowable_order() as it is an
+anonymous-mmap, but then be collapsed as a file-mmap.
+
+It seems the problem has existed for a long time, but actually, since we
+have khugepaged_max_ptes_none check before, we will skip collapse it as it
+is /dev/zero and so has no present page.  But commit d8ea7cc8547c limit
+the check for only khugepaged, so the BUG_ON() can be triggered by
+madvise_collapse().
+
+Add vma_is_anonymous() check to make such vma be processed by
+hpage_collapse_scan_pmd().
+
+Link: https://lkml.kernel.org/r/20250111034511.2223353-1-liushixin2@huawei.com
+Fixes: d8ea7cc8547c ("mm/khugepaged: add flag to predicate khugepaged-only behavior")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+Reviewed-by: Yang Shi <yang@os.amperecomputing.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: Chengming Zhou <chengming.zhou@linux.dev>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Mattew Wilcox <willy@infradead.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Qi Zheng <zhengqi.arch@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[acsjakub: backport, clean apply]
+Signed-off-by: Jakub Acs <acsjakub@amazon.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/khugepaged.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -2387,7 +2387,7 @@ skip:
+                       VM_BUG_ON(khugepaged_scan.address < hstart ||
+                                 khugepaged_scan.address + HPAGE_PMD_SIZE >
+                                 hend);
+-                      if (IS_ENABLED(CONFIG_SHMEM) && vma->vm_file) {
++                      if (IS_ENABLED(CONFIG_SHMEM) && !vma_is_anonymous(vma)) {
+                               struct file *file = get_file(vma->vm_file);
+                               pgoff_t pgoff = linear_page_index(vma,
+                                               khugepaged_scan.address);
+@@ -2734,7 +2734,7 @@ int madvise_collapse(struct vm_area_stru
+               mmap_assert_locked(mm);
+               memset(cc->node_load, 0, sizeof(cc->node_load));
+               nodes_clear(cc->alloc_nmask);
+-              if (IS_ENABLED(CONFIG_SHMEM) && vma->vm_file) {
++              if (IS_ENABLED(CONFIG_SHMEM) && !vma_is_anonymous(vma)) {
+                       struct file *file = get_file(vma->vm_file);
+                       pgoff_t pgoff = linear_page_index(vma, addr);
index ea3cb8301c5cd233bb6650f222445d0b3aaca48a..db0ccbac3cb72bdc323b05adadc80c6500e66433 100644 (file)
@@ -55,3 +55,5 @@ comedi-comedi_test-fix-possible-deletion-of-uninitialized-timers.patch
 alsa-hda-tegra-add-tegra264-support.patch
 alsa-hda-add-missing-nvidia-hda-codec-ids.patch
 drm-i915-dp-fix-2.7-gbps-dp_link_bw-value-on-g4x.patch
+mm-khugepaged-fix-call-hpage_collapse_scan_file-for-anonymous-vma.patch
+erofs-address-d-cache-aliasing.patch