From: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]>, Ingo Molnar <[EMAIL 
PROTECTED]>

This patch may or may not be wanted. I took this from the original Ingo's
patch and improved it, but probably we want to keep this bug. However, I'm not
sure of what Ingo wanted to do.

If on a private writable mapping we call remap_file_pages() without
altering the file offset or the protections, after writing on the page to
create a COW mapping, with this patch we refuse reinstalling the old page, as
we should.

However, I'm not sure there's a point for an app to do this.

It is possible that we return an error even if the present page is already the
same one; however, that shouldn't be a big problem. In fact, the main purpose
of supporting private VMAs in remap_file_pages is allowing mmap(MAP_PRIVATE |
MAP_POPULATE) to work, and for that case existing mappings have already been
cleared and this patch is unneeded.

Note that this patch *needs* testing on each existing arch - I already got
subtle failures on i386 and not on UML on this patch (I had forgot to test
pte_present(), and pte_file() returned true, because _PAGE_DIRTY and
_PAGE_FILE share the same slot).

Setting CONFIG_DEBUG_PRIVATE in the test-program provides a mean to test this.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]>
---

 linux-2.6.git-paolo/mm/fremap.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+)

diff -puN mm/fremap.c~rfp-notrunc-priv-mappings mm/fremap.c
--- linux-2.6.git/mm/fremap.c~rfp-notrunc-priv-mappings 2005-08-24 
20:57:34.000000000 +0200
+++ linux-2.6.git-paolo/mm/fremap.c     2005-08-24 20:57:34.000000000 +0200
@@ -94,6 +94,16 @@ int install_page(struct mm_struct *mm, s
        if (!page->mapping || page->index >= size)
                goto err_unlock;
 
+       /*
+        * On private (and thus uniform) mapping, we don't want to truncate COW
+        * page, so we can only override pte_none or pte_file PTEs, not swap or
+        * present ones.
+        */
+       err = -EEXIST;
+       if (unlikely(!(vma->vm_flags & VM_SHARED)) && (pte_present(*pte) ||
+                               (!pte_none(*pte) && !pte_file(*pte))))
+               goto err_unlock;
+
        zap_pte(mm, vma, addr, pte);
 
        inc_mm_counter(mm,rss);
@@ -155,6 +165,15 @@ int install_file_pte(struct mm_struct *m
        err = 0;
        if (uniform && pte_none(*pte))
                goto err_unlock;
+       /*
+        * On private (and thus uniform) mapping, we don't want to truncate COW
+        * page, so we can only override pte_none or pte_file PTEs, not swap or
+        * present ones.
+        */
+       err = -EEXIST;
+       if (unlikely(!(vma->vm_flags & VM_SHARED)) && (pte_present(*pte) ||
+                               (!pte_none(*pte) && !pte_file(*pte))))
+               goto err_unlock;
 
        err = 0;
        zap_pte(mm, vma, addr, pte);
_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to