--- /dev/null
+From 61e150fb310729c98227a5edf6e4a3619edc3702 Mon Sep 17 00:00:00 2001
+From: Helge Deller <deller@gmx.de>
+Date: Wed, 24 May 2023 17:07:07 +0200
+Subject: parisc: Fix flush_dcache_page() for usage from irq context
+
+From: Helge Deller <deller@gmx.de>
+
+commit 61e150fb310729c98227a5edf6e4a3619edc3702 upstream.
+
+Since at least kernel 6.1, flush_dcache_page() is called with IRQs
+disabled, e.g. from aio_complete().
+
+But the current implementation for flush_dcache_page() on parisc
+unintentionally re-enables IRQs, which may lead to deadlocks.
+
+Fix it by using xa_lock_irqsave() and xa_unlock_irqrestore()
+for the flush_dcache_mmap_*lock() macros instead.
+
+Cc: linux-parisc@vger.kernel.org
+Cc: stable@kernel.org # 5.18+
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/parisc/include/asm/cacheflush.h | 5 +++++
+ arch/parisc/kernel/cache.c | 5 +++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/arch/parisc/include/asm/cacheflush.h
++++ b/arch/parisc/include/asm/cacheflush.h
+@@ -57,6 +57,11 @@ extern void flush_dcache_page(struct pag
+
+ #define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages)
+ #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
++#define flush_dcache_mmap_lock_irqsave(mapping, flags) \
++ xa_lock_irqsave(&mapping->i_pages, flags)
++#define flush_dcache_mmap_unlock_irqrestore(mapping, flags) \
++ xa_unlock_irqrestore(&mapping->i_pages, flags)
++
+
+ #define flush_icache_page(vma,page) do { \
+ flush_kernel_dcache_page(page); \
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -328,6 +328,7 @@ void flush_dcache_page(struct page *page
+ struct vm_area_struct *mpnt;
+ unsigned long offset;
+ unsigned long addr, old_addr = 0;
++ unsigned long flags;
+ pgoff_t pgoff;
+
+ if (mapping && !mapping_mapped(mapping)) {
+@@ -347,7 +348,7 @@ void flush_dcache_page(struct page *page
+ * declared as MAP_PRIVATE or MAP_SHARED), so we only need
+ * to flush one address here for them all to become coherent */
+
+- flush_dcache_mmap_lock(mapping);
++ flush_dcache_mmap_lock_irqsave(mapping, flags);
+ vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
+ offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
+ addr = mpnt->vm_start + offset;
+@@ -370,7 +371,7 @@ void flush_dcache_page(struct page *page
+ old_addr = addr;
+ }
+ }
+- flush_dcache_mmap_unlock(mapping);
++ flush_dcache_mmap_unlock_irqrestore(mapping, flags);
+ }
+ EXPORT_SYMBOL(flush_dcache_page);
+