[MIPS] Fix aliasing bug in copy_user_highpage.
authorRalf Baechle <ralf@linux-mips.org>
Tue, 11 Sep 2007 17:05:33 +0000 (18:05 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 11 Sep 2007 18:03:26 +0000 (19:03 +0100)
Copy_user_highpage was written assuming it was only being called for
breaking COW pages in which case the source page isn't cached as in
marked cachable under it kernel virtual address.  If it is called anyway
the aliasing avoidance strategy implemented by kmap_coherent will fail.
Avoid the use of kmap_coherent for pages marked dirty and to avoid
another instance of this sort of bug, place a BUG_ON in kmap_coherent.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/mm/init.c

index 09d91505b90cd5373832fac820b1b6d49229a10e..5240432e6d1d6d93b385fd0dbc54454dbb040503 100644 (file)
@@ -8,6 +8,7 @@
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
  */
+#include <linux/bug.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/signal.h>
@@ -132,6 +133,8 @@ void *kmap_coherent(struct page *page, unsigned long addr)
        pte_t pte;
        int tlbidx;
 
+       BUG_ON(Page_dcache_dirty(page));
+
        inc_preempt_count();
        idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
 #ifdef CONFIG_MIPS_MT_SMTC
@@ -208,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from,
        void *vfrom, *vto;
 
        vto = kmap_atomic(to, KM_USER1);
-       if (cpu_has_dc_aliases) {
+       if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) {
                vfrom = kmap_coherent(from, vaddr);
                copy_page(vto, vfrom);
                kunmap_coherent();