--- /dev/null
+From bd5603eaae0aabf527bfb3ce1bb07e979ce5bd50 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Fri, 10 Oct 2025 15:07:38 -0700
+Subject: fuse: fix readahead reclaim deadlock
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit bd5603eaae0aabf527bfb3ce1bb07e979ce5bd50 upstream.
+
+Commit e26ee4efbc79 ("fuse: allocate ff->release_args only if release is
+needed") skips allocating ff->release_args if the server does not
+implement open. However in doing so, fuse_prepare_release() now skips
+grabbing the reference on the inode, which makes it possible for an
+inode to be evicted from the dcache while there are inflight readahead
+requests. This causes a deadlock if the server triggers reclaim while
+servicing the readahead request and reclaim attempts to evict the inode
+of the file being read ahead. Since the folio is locked during
+readahead, when reclaim evicts the fuse inode and fuse_evict_inode()
+attempts to remove all folios associated with the inode from the page
+cache (truncate_inode_pages_range()), reclaim will block forever waiting
+for the lock since readahead cannot relinquish the lock because it is
+itself blocked in reclaim:
+
+>>> stack_trace(1504735)
+ folio_wait_bit_common (mm/filemap.c:1308:4)
+ folio_lock (./include/linux/pagemap.h:1052:3)
+ truncate_inode_pages_range (mm/truncate.c:336:10)
+ fuse_evict_inode (fs/fuse/inode.c:161:2)
+ evict (fs/inode.c:704:3)
+ dentry_unlink_inode (fs/dcache.c:412:3)
+ __dentry_kill (fs/dcache.c:615:3)
+ shrink_kill (fs/dcache.c:1060:12)
+ shrink_dentry_list (fs/dcache.c:1087:3)
+ prune_dcache_sb (fs/dcache.c:1168:2)
+ super_cache_scan (fs/super.c:221:10)
+ do_shrink_slab (mm/shrinker.c:435:9)
+ shrink_slab (mm/shrinker.c:626:10)
+ shrink_node (mm/vmscan.c:5951:2)
+ shrink_zones (mm/vmscan.c:6195:3)
+ do_try_to_free_pages (mm/vmscan.c:6257:3)
+ do_swap_page (mm/memory.c:4136:11)
+ handle_pte_fault (mm/memory.c:5562:10)
+ handle_mm_fault (mm/memory.c:5870:9)
+ do_user_addr_fault (arch/x86/mm/fault.c:1338:10)
+ handle_page_fault (arch/x86/mm/fault.c:1481:3)
+ exc_page_fault (arch/x86/mm/fault.c:1539:2)
+ asm_exc_page_fault+0x22/0x27
+
+Fix this deadlock by allocating ff->release_args and grabbing the
+reference on the inode when preparing the file for release even if the
+server does not implement open. The inode reference will be dropped when
+the last reference on the fuse file is dropped (see fuse_file_put() ->
+fuse_release_end()).
+
+Fixes: e26ee4efbc79 ("fuse: allocate ff->release_args only if release is needed")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Reported-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/file.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -109,7 +109,9 @@ static void fuse_file_put(struct fuse_fi
+ fuse_file_io_release(ff, ra->inode);
+
+ if (!args) {
+- /* Do nothing when server does not implement 'open' */
++ /* Do nothing when server does not implement 'opendir' */
++ } else if (args->opcode == FUSE_RELEASE && ff->fm->fc->no_open) {
++ fuse_release_end(ff->fm, args, 0);
+ } else if (sync) {
+ fuse_simple_request(ff->fm, args);
+ fuse_release_end(ff->fm, args, 0);
+@@ -130,8 +132,17 @@ struct fuse_file *fuse_file_open(struct
+ struct fuse_file *ff;
+ int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+ bool open = isdir ? !fc->no_opendir : !fc->no_open;
++ bool release = !isdir || open;
+
+- ff = fuse_file_alloc(fm, open);
++ /*
++ * ff->args->release_args still needs to be allocated (so we can hold an
++ * inode reference while there are pending inflight file operations when
++ * ->release() is called, see fuse_prepare_release()) even if
++ * fc->no_open is set else it becomes possible for reclaim to deadlock
++ * if while servicing the readahead request the server triggers reclaim
++ * and reclaim evicts the inode of the file being read ahead.
++ */
++ ff = fuse_file_alloc(fm, release);
+ if (!ff)
+ return ERR_PTR(-ENOMEM);
+
+@@ -151,13 +162,14 @@ struct fuse_file *fuse_file_open(struct
+ fuse_file_free(ff);
+ return ERR_PTR(err);
+ } else {
+- /* No release needed */
+- kfree(ff->args);
+- ff->args = NULL;
+- if (isdir)
++ if (isdir) {
++ /* No release needed */
++ kfree(ff->args);
++ ff->args = NULL;
+ fc->no_opendir = 1;
+- else
++ } else {
+ fc->no_open = 1;
++ }
+ }
+ }
+
--- /dev/null
+From de83d4617f9fe059623e97acf7e1e10d209625b5 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 20 Oct 2025 06:53:10 +0200
+Subject: iommu/mediatek: fix use-after-free on probe deferral
+
+From: Johan Hovold <johan@kernel.org>
+
+commit de83d4617f9fe059623e97acf7e1e10d209625b5 upstream.
+
+The driver is dropping the references taken to the larb devices during
+probe after successful lookup as well as on errors. This can
+potentially lead to a use-after-free in case a larb device has not yet
+been bound to its driver so that the iommu driver probe defers.
+
+Fix this by keeping the references as expected while the iommu driver is
+bound.
+
+Fixes: 26593928564c ("iommu/mediatek: Add error path for loop of mm_dts_parse")
+Cc: stable@vger.kernel.org
+Cc: Yong Wu <yong.wu@mediatek.com>
+Acked-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Yong Wu <yong.wu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/mtk_iommu.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1213,16 +1213,19 @@ static int mtk_iommu_mm_dts_parse(struct
+ }
+
+ component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
+- platform_device_put(plarbdev);
+ }
+
+- if (!frst_avail_smicomm_node)
+- return -EINVAL;
++ if (!frst_avail_smicomm_node) {
++ ret = -EINVAL;
++ goto err_larbdev_put;
++ }
+
+ pcommdev = of_find_device_by_node(frst_avail_smicomm_node);
+ of_node_put(frst_avail_smicomm_node);
+- if (!pcommdev)
+- return -ENODEV;
++ if (!pcommdev) {
++ ret = -ENODEV;
++ goto err_larbdev_put;
++ }
+ data->smicomm_dev = &pcommdev->dev;
+
+ link = device_link_add(data->smicomm_dev, dev,
+@@ -1230,7 +1233,8 @@ static int mtk_iommu_mm_dts_parse(struct
+ platform_device_put(pcommdev);
+ if (!link) {
+ dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err_larbdev_put;
+ }
+ return 0;
+
+@@ -1402,8 +1406,12 @@ out_sysfs_remove:
+ iommu_device_sysfs_remove(&data->iommu);
+ out_list_del:
+ list_del(&data->list);
+- if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
++ if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+ device_link_remove(data->smicomm_dev, dev);
++
++ for (i = 0; i < MTK_LARB_NR_MAX; i++)
++ put_device(data->larb_imu[i].dev);
++ }
+ out_runtime_disable:
+ pm_runtime_disable(dev);
+ return ret;
+@@ -1423,6 +1431,9 @@ static void mtk_iommu_remove(struct plat
+ if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+ device_link_remove(data->smicomm_dev, &pdev->dev);
+ component_master_del(&pdev->dev, &mtk_iommu_com_ops);
++
++ for (i = 0; i < MTK_LARB_NR_MAX; i++)
++ put_device(data->larb_imu[i].dev);
+ }
+ pm_runtime_disable(&pdev->dev);
+ for (i = 0; i < data->plat_data->banks_num; i++) {