[ARM] 4078/1: Fix ARM copypage cache coherency problems

If PG_dcache_dirty is set for a page, we need to flush the source page
before performing any copypage operation using a different virtual address.

This fixes the copypage implementations for XScale, StrongARM and ARMv6.

This patch fixes segmentation faults seen in the dynamic linker under
the usage patterns in glibc 2.4/2.5.

Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index aea5da7..2e455f8 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -19,6 +19,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 
 #include "mm.h"
 
@@ -91,6 +92,11 @@
 
 void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
 {
+	struct page *page = virt_to_page(kfrom);
+
+	if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
+		__flush_dcache_page(page_mapping(page), page);
+
 	spin_lock(&minicache_lock);
 
 	set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);