[MIPS] Fix aliasing bug in copy_user_highpage, take 2.

2007-10-16 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=985c30ef4d7c2a4f0e979a507a7e2f7f09b096c3
Commit: 985c30ef4d7c2a4f0e979a507a7e2f7f09b096c3
Parent: 736fad17b89e5e718908abb76ae9bce210a9d5d4
Author: Ralf Baechle [EMAIL PROTECTED]
AuthorDate: Mon Oct 15 16:30:24 2007 +0100
Committer:  Ralf Baechle [EMAIL PROTECTED]
CommitDate: Tue Oct 16 18:23:49 2007 +0100

[MIPS] Fix aliasing bug in copy_user_highpage, take 2.

Turns out b868868ae0f7272228c95cc760338ffe35bb739d  wasn't quite right.
When called for a page that isn't marked dirty it would artificially
create an alias instead of doing the obvious thing and access the page
via KSEG0.

The same issue also exists in copy_to_user_page and copy_from_user_page
which was causing the machine to die under rare circumstances for example
when running ps if the BUG_ON() assertion added by the earlier fix was
getting triggered.

Signed-off-by: Ralf Baechle [EMAIL PROTECTED]
---
 arch/mips/mm/init.c |   19 ---
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 5240432..110ee76 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -211,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  !Page_dcache_dirty(from)) {
+   if (cpu_has_dc_aliases  page_mapped(from)) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
kunmap_coherent();
@@ -234,12 +234,15 @@ void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
 {
-   if (cpu_has_dc_aliases) {
+   if (cpu_has_dc_aliases  page_mapped(page)) {
void *vto = kmap_coherent(page, vaddr) + (vaddr  ~PAGE_MASK);
memcpy(vto, src, len);
kunmap_coherent();
-   } else
+   } else {
memcpy(dst, src, len);
+   if (cpu_has_dc_aliases)
+   SetPageDcacheDirty(page);
+   }
if ((vma-vm_flags  VM_EXEC)  !cpu_has_ic_fills_f_dc)
flush_cache_page(vma, vaddr, page_to_pfn(page));
 }
@@ -250,13 +253,15 @@ void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len)
 {
-   if (cpu_has_dc_aliases) {
-   void *vfrom =
-   kmap_coherent(page, vaddr) + (vaddr  ~PAGE_MASK);
+   if (cpu_has_dc_aliases  page_mapped(page)) {
+   void *vfrom = kmap_coherent(page, vaddr) + (vaddr  ~PAGE_MASK);
memcpy(dst, vfrom, len);
kunmap_coherent();
-   } else
+   } else {
memcpy(dst, src, len);
+   if (cpu_has_dc_aliases)
+   SetPageDcacheDirty(page);
+   }
 }
 
 EXPORT_SYMBOL(copy_from_user_page);
-
To unsubscribe from this list: send the line unsubscribe git-commits-head in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[MIPS] Fix aliasing bug in copy_user_highpage.

2007-09-11 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b868868ae0f7272228c95cc760338ffe35bb739d
Commit: b868868ae0f7272228c95cc760338ffe35bb739d
Parent: 01e9943c79ad4edb2c0b76c99029e34d704223ce
Author: Ralf Baechle [EMAIL PROTECTED]
AuthorDate: Tue Sep 11 18:05:33 2007 +0100
Committer:  Ralf Baechle [EMAIL PROTECTED]
CommitDate: Tue Sep 11 19:03:26 2007 +0100

[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 [EMAIL PROTECTED]
---
 arch/mips/mm/init.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 09d9150..5240432 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -8,6 +8,7 @@
  * Kevin D. Kissell, [EMAIL PROTECTED] and Carsten Langgaard, [EMAIL PROTECTED]
  * 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();
-
To unsubscribe from this list: send the line unsubscribe git-commits-head in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html