On Thu, Oct 12, 2000 at 01:18:53PM -0700, Linus Torvalds wrote:
> See the arch/x86/mm/fault.c changes to see what arch-specific changes this
> can entail.
> 
This patch works for me...

Ivan.

--- linux/include/asm-alpha/bitops.h.orig       Wed Oct  4 17:06:59 2000
+++ linux/include/asm-alpha/bitops.h    Fri Oct 13 13:41:02 2000
@@ -2,7 +2,6 @@
 #define _ALPHA_BITOPS_H
 
 #include <linux/config.h>
-#include <linux/kernel.h>
 
 /*
  * Copyright 1994, Linus Torvalds.
--- linux/include/asm-alpha/pgalloc.h.orig      Mon Aug 14 17:32:04 2000
+++ linux/include/asm-alpha/pgalloc.h   Fri Oct 13 13:44:44 2000
@@ -378,20 +378,4 @@ extern inline pmd_t * pmd_alloc(pgd_t *p
 
 extern int do_check_pgt_cache(int, int);
 
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-       struct task_struct * p;
-       pgd_t *pgd;
-        
-       read_lock(&tasklist_lock);
-       for_each_task(p) {
-               if (!p->mm)
-                       continue;
-               *pgd_offset(p->mm,address) = entry;
-       }
-       read_unlock(&tasklist_lock);
-       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-               pgd[(address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)] = entry;
-}
-
 #endif /* _ALPHA_PGALLOC_H */
--- linux/arch/alpha/mm/fault.c.orig    Wed Oct  4 17:06:45 2000
+++ linux/arch/alpha/mm/fault.c Fri Oct 13 19:52:43 2000
@@ -108,6 +108,9 @@ do_page_fault(unsigned long address, uns
        if (!mm || in_interrupt())
                goto no_context;
 
+       if (address >= TASK_SIZE)
+               goto vmalloc_fault;
+
        down(&mm->mmap_sem);
        vma = find_vma(mm, address);
        if (!vma)
@@ -157,6 +160,7 @@ good_area:
 bad_area:
        up(&mm->mmap_sem);
 
+bad_area_nosemaphore:
        if (user_mode(regs)) {
                force_sig(SIGSEGV, current);
                return;
@@ -204,4 +208,33 @@ do_sigbus:
        if (!user_mode(regs))
                goto no_context;
        return;
+
+vmalloc_fault:
+       {
+               /*
+                * Synchronize this task's top level page-table
+                * with the 'reference' page table.
+                */
+               int offset = __pgd_offset(address);
+               pgd_t *pgd, *pgd_k;
+               pmd_t *pmd, *pmd_k;
+
+               pgd = current->active_mm->pgd + offset;
+               pgd_k = init_mm.pgd + offset;
+
+               if (!pgd_present(*pgd)) {
+                       if (!pgd_present(*pgd_k))
+                               goto bad_area_nosemaphore;
+                       pgd_val(*pgd) = pgd_val(*pgd_k);
+                       return;
+               }
+
+               pmd = pmd_offset(pgd, address);
+               pmd_k = pmd_offset(pgd_k, address);
+
+               if (pmd_present(*pmd) || !pmd_present(*pmd_k))
+                       goto bad_area_nosemaphore;
+               pmd_val(*pmd) = pmd_val(*pmd_k);
+               return;
+       }
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to