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

We got unflushed PTE's marked up-to-date, because they were protected to get
dirtying / accessing faults. So, don't test the PTE for being up-to-date, but
check directly the permission (since the PTE is not protected for that).

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

 linux-2.6.git-paolo/arch/um/kernel/trap_kern.c |   28 +++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diff -puN arch/um/kernel/trap_kern.c~rfp-sigsegv-uml-3-fix 
arch/um/kernel/trap_kern.c
--- linux-2.6.git/arch/um/kernel/trap_kern.c~rfp-sigsegv-uml-3-fix      
2005-08-11 23:14:58.000000000 +0200
+++ linux-2.6.git-paolo/arch/um/kernel/trap_kern.c      2005-08-11 
23:14:58.000000000 +0200
@@ -35,7 +35,7 @@ int handle_page_fault(unsigned long addr
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
-       pte_t *pte;
+       pte_t *pte, entry;
        int err = -EFAULT;
        int access_mask = 0;
 
@@ -75,16 +75,32 @@ handle_fault:
                        err = -EACCES;
                        goto out;
                case VM_FAULT_SIGSEGV:
+                       WARN_ON(!(vma->vm_flags & VM_NONUNIFORM));
                        /* Duplicate this code here. */
                        pgd = pgd_offset(mm, address);
                        pud = pud_offset(pgd, address);
                        pmd = pmd_offset(pud, address);
                        pte = pte_offset_kernel(pmd, address);
-                       if (likely (pte_newpage(*pte) || pte_newprot(*pte))) {
-                               /* This wasn't done by __handle_mm_fault(), and
-                                * the page hadn't been flushed. */
-                               *pte = pte_mkyoung(*pte);
-                               if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
+                       if (likely (pte_newpage(*pte) || pte_newprot(*pte)) ||
+                               (is_write ? pte_write(*pte) : pte_read(*pte)) ) 
{
+                               /* The page hadn't been flushed, or it had been
+                                * flushed but without access to get a dirtying
+                                * / accessing fault. */
+
+                               /* __handle_mm_fault() didn't dirty / young this
+                                * PTE, probably we won't get another fault for
+                                * this page, so fix things now. */
+                               entry = *pte;
+                               entry = pte_mkyoung(*pte);
+                               if(pte_write(entry))
+                                       entry = pte_mkdirty(entry);
+                               /* Yes, this will set the page as NEWPAGE. We
+                                * want this, otherwise things won't work.
+                                * Indeed, the
+                                * *pte = pte_mkyoung(*pte);
+                                * we used to have (uselessly) didn't work at
+                                * all! */
+                               set_pte(pte, entry);
                                break;
                        } else {
                                err = -EFAULT;
_
-
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