--- /dev/null
+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)
--- /dev/null
+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);
+