aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
authorStuart Menefy <stuart.menefy@st.com>2011-01-31 12:50:29 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-02-15 02:24:31 -0500
commita25bbe12224e649fe12cba7a2fa920180a35c8a9 (patch)
tree2c4b07a6e106551b70f3c48e5ce32824e3168a1e /arch/sh/mm
parenta086536858ad0eb51c58074af2fc2c89ba9c1f5e (diff)
sh: Flush executable pages in copy_user_highpage
This resolves a problem seen when using the Android dynamic linker. Sometimes the dynamic linker would seg-fault at start up and this was eventually traced to the handling of a COW fault for a page which was being modified by the linker. If there was no cache aliasing between the kernel and the user page, the page was not flushed, leaving the newly copied data in the D-cache. However when executing instructions from that page, the I-cache is filled directly from external memory, rather than the D-cache, and causing garbage to be executed. Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/cache.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 88d3dc3d30d5..5a580ea04429 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -108,7 +108,8 @@ void copy_user_highpage(struct page *to, struct page *from,
108 kunmap_atomic(vfrom, KM_USER0); 108 kunmap_atomic(vfrom, KM_USER0);
109 } 109 }
110 110
111 if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) 111 if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK) ||
112 (vma->vm_flags & VM_EXEC))
112 __flush_purge_region(vto, PAGE_SIZE); 113 __flush_purge_region(vto, PAGE_SIZE);
113 114
114 kunmap_atomic(vto, KM_USER1); 115 kunmap_atomic(vto, KM_USER1);