aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-09-11 13:05:33 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-09-11 14:03:26 -0400
commitb868868ae0f7272228c95cc760338ffe35bb739d (patch)
tree71ed6189bc2dddd3f79aae0969e41381f905a709 /arch
parent01e9943c79ad4edb2c0b76c99029e34d704223ce (diff)
[MIPS] Fix aliasing bug in copy_user_highpage.
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/mm/init.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 09d91505b90c..5240432e6d1d 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -8,6 +8,7 @@
8 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com 8 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
9 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. 9 * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
10 */ 10 */
11#include <linux/bug.h>
11#include <linux/init.h> 12#include <linux/init.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/signal.h> 14#include <linux/signal.h>
@@ -132,6 +133,8 @@ void *kmap_coherent(struct page *page, unsigned long addr)
132 pte_t pte; 133 pte_t pte;
133 int tlbidx; 134 int tlbidx;
134 135
136 BUG_ON(Page_dcache_dirty(page));
137
135 inc_preempt_count(); 138 inc_preempt_count();
136 idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); 139 idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
137#ifdef CONFIG_MIPS_MT_SMTC 140#ifdef CONFIG_MIPS_MT_SMTC
@@ -208,7 +211,7 @@ void copy_user_highpage(struct page *to, struct page *from,
208 void *vfrom, *vto; 211 void *vfrom, *vto;
209 212
210 vto = kmap_atomic(to, KM_USER1); 213 vto = kmap_atomic(to, KM_USER1);
211 if (cpu_has_dc_aliases) { 214 if (cpu_has_dc_aliases && !Page_dcache_dirty(from)) {
212 vfrom = kmap_coherent(from, vaddr); 215 vfrom = kmap_coherent(from, vaddr);
213 copy_page(vto, vfrom); 216 copy_page(vto, vfrom);
214 kunmap_coherent(); 217 kunmap_coherent();