--- /dev/null
+From 234859e49a15323cf1b2331bdde7f658c4cb45fb Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Tue, 1 Mar 2016 02:37:57 +0000
+Subject: MIPS: Flush highmem pages in __flush_dcache_page
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+commit 234859e49a15323cf1b2331bdde7f658c4cb45fb upstream.
+
+When flush_dcache_page is called on an executable page, that page is
+about to be provided to userland & we can presume that the icache
+contains no valid entries for its address range. However if the icache
+does not fill from the dcache then we cannot presume that the pages
+content has been written back as far as the memories that the dcache
+will fill from (ie. L2 or further out).
+
+This was being done for lowmem pages, but not for highmem which can lead
+to icache corruption. Fix this by mapping highmem pages & flushing their
+content from the dcache in __flush_dcache_page before providing the page
+to userland, just as is done for lowmem pages.
+
+Signed-off-by: Paul Burton <paul.burton@imgtec.com>
+Cc: Lars Persson <lars.persson@axis.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/12720/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/mm/cache.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -16,6 +16,7 @@
+ #include <linux/mm.h>
+
+ #include <asm/cacheflush.h>
++#include <asm/highmem.h>
+ #include <asm/processor.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
+@@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *pa
+ struct address_space *mapping = page_mapping(page);
+ unsigned long addr;
+
+- if (PageHighMem(page))
+- return;
+ if (mapping && !mapping_mapped(mapping)) {
+ SetPageDcacheDirty(page);
+ return;
+@@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *pa
+ * case is for exec env/arg pages and those are %99 certainly going to
+ * get faulted into the tlb (and thus flushed) anyways.
+ */
+- addr = (unsigned long) page_address(page);
++ if (PageHighMem(page))
++ addr = (unsigned long)kmap_atomic(page);
++ else
++ addr = (unsigned long)page_address(page);
++
+ flush_data_cache_page(addr);
++
++ if (PageHighMem(page))
++ __kunmap_atomic((void *)addr);
+ }
+
+ EXPORT_SYMBOL(__flush_dcache_page);