]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 28 May 2023 07:44:36 +0000 (08:44 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 28 May 2023 07:44:36 +0000 (08:44 +0100)
added patches:
parisc-fix-flush_dcache_page-for-usage-from-irq-context.patch

queue-4.19/parisc-fix-flush_dcache_page-for-usage-from-irq-context.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/parisc-fix-flush_dcache_page-for-usage-from-irq-context.patch b/queue-4.19/parisc-fix-flush_dcache_page-for-usage-from-irq-context.patch
new file mode 100644 (file)
index 0000000..e22b387
--- /dev/null
@@ -0,0 +1,69 @@
+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
+@@ -309,6 +309,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)) {
+@@ -328,7 +329,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;
+@@ -351,7 +352,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);
index a0f8e759a4ac8faa0790592052f33c222ad19a4a..9ebf3fa72bd2ea6b01e3008d4bf4fcf7a5a07521 100644 (file)
@@ -109,3 +109,4 @@ parisc-allow-to-reboot-machine-after-system-halt.patch
 btrfs-use-nofs-when-cleaning-up-aborted-transactions.patch
 x86-mm-avoid-incomplete-global-invlpg-flushes.patch
 selftests-memfd-fix-unknown-type-name-build-failure.patch
+parisc-fix-flush_dcache_page-for-usage-from-irq-context.patch