vserver 1.9.5.x5
[linux-2.6.git] / arch / um / kernel / trap_kern.c
index cba33ef..47e766e 100644 (file)
@@ -13,6 +13,7 @@
 #include "linux/ptrace.h"
 #include "asm/semaphore.h"
 #include "asm/pgtable.h"
+#include "asm/pgalloc.h"
 #include "asm/tlbflush.h"
 #include "asm/a.out.h"
 #include "asm/current.h"
@@ -32,6 +33,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        pgd_t *pgd;
+       pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        unsigned long page;
@@ -46,6 +48,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
                goto good_area;
        else if(!(vma->vm_flags & VM_GROWSDOWN)) 
                goto out;
+       else if(!ARCH_IS_STACKGROW(address))
+               goto out;
        else if(expand_stack(vma, address)) 
                goto out;
 
@@ -55,7 +59,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
                goto out;
        page = address & PAGE_MASK;
        pgd = pgd_offset(mm, page);
-       pmd = pmd_offset(pgd, page);
+       pud = pud_offset(pgd, page);
+       pmd = pmd_offset(pud, page);
        do {
  survive:
                switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -74,6 +79,9 @@ int handle_page_fault(unsigned long address, unsigned long ip,
                default:
                        BUG();
                }
+               pgd = pgd_offset(mm, page);
+               pud = pud_offset(pgd, page);
+               pmd = pmd_offset(pud, page);
                pte = pte_offset_kernel(pmd, page);
        } while(!pte_present(*pte));
        err = 0;
@@ -215,7 +223,7 @@ void trap_init(void)
 {
 }
 
-spinlock_t trap_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(trap_lock);
 
 static int trap_index = 0;