Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77fff4ae2b7bba6d66a8287d9ab948e2b6c16145
Commit:     77fff4ae2b7bba6d66a8287d9ab948e2b6c16145
Parent:     1fb8cacc19dfe408a5dd758235561c58cadea174
Author:     Atsushi Nemoto <[EMAIL PROTECTED]>
AuthorDate: Tue Dec 12 17:14:54 2006 +0000
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Dec 13 09:27:07 2006 -0800

    [PATCH] Fix COW D-cache aliasing on fork
    
    Problem:
    
    1. There is a process containing two thread (T1 and T2).  The
       thread T1 calls fork().  Then dup_mmap() function called on T1 context.
    
    static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
        ...
        flush_cache_mm(current->mm);
        ...     /* A */
        (write-protect all Copy-On-Write pages)
        ...     /* B */
        flush_tlb_mm(current->mm);
        ...
    
    2. When preemption happens between A and B (or on SMP kernel), the
       thread T2 can run and modify data on COW pages without page fault
       (modified data will stay in cache).
    
    3. Some time after fork() completed, the thread T2 may cause a page
       fault by write-protect on a COW page.
    
    4. Then data of the COW page will be copied to newly allocated
       physical page (copy_cow_page()).  It reads data via kernel mapping.
       The kernel mapping can have different 'color' with user space
       mapping of the thread T2 (dcache aliasing).  Therefore
       copy_cow_page() will copy stale data.  Then the modified data in
       cache will be lost.
    
    In order to allow architecture code to deal with this problem allow
    architecture code to override copy_user_highpage() by defining
    __HAVE_ARCH_COPY_USER_HIGHPAGE in <asm/page.h>.
    
    The main part of this patch was originally written by Ralf Baechle;
    Atushi Nemoto did the the debugging.
    
    Signed-off-by: Atsushi Nemoto <[EMAIL PROTECTED]>
    Signed-off-by: Ralf Baechle <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 include/linux/highmem.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 3d8768b..ea5780b 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -96,6 +96,8 @@ static inline void memclear_highpage_flush(struct page *page, 
unsigned int offse
        kunmap_atomic(kaddr, KM_USER0);
 }
 
+#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
+
 static inline void copy_user_highpage(struct page *to, struct page *from, 
unsigned long vaddr)
 {
        char *vfrom, *vto;
@@ -109,6 +111,8 @@ static inline void copy_user_highpage(struct page *to, 
struct page *from, unsign
        smp_wmb();
 }
 
+#endif
+
 static inline void copy_highpage(struct page *to, struct page *from)
 {
        char *vfrom, *vto;
-
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

Reply via email to