vserver 1.9.5.x5
[linux-2.6.git] / arch / x86_64 / ia32 / syscall32.c
index f82aeae..399ff49 100644 (file)
@@ -28,7 +28,7 @@ extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
 extern int sysctl_vsyscall32;
 
 char *syscall32_page; 
-static int use_sysenter __initdata = -1;
+static int use_sysenter = -1;
 
 /*
  * Map the 32bit vsyscall page on demand.
@@ -40,23 +40,30 @@ static int use_sysenter __initdata = -1;
  */
 int __map_syscall32(struct mm_struct *mm, unsigned long address)
 { 
+       pgd_t *pgd;
+       pud_t *pud;
        pte_t *pte;
        pmd_t *pmd;
-       int err = 0;
+       int err = -ENOMEM;
 
        spin_lock(&mm->page_table_lock); 
-       pmd = pmd_alloc(mm, pgd_offset(mm, address), address); 
-       if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { 
-               if (pte_none(*pte)) { 
-                       set_pte(pte, 
-                               mk_pte(virt_to_page(syscall32_page), 
-                                      PAGE_KERNEL_VSYSCALL)); 
+       pgd = pgd_offset(mm, address);
+       pud = pud_alloc(mm, pgd, address);
+       if (pud) {
+               pmd = pmd_alloc(mm, pud, address);
+               if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) {
+                       if (pte_none(*pte)) {
+                               set_pte(pte,
+                                       mk_pte(virt_to_page(syscall32_page),
+                                              PAGE_KERNEL_VSYSCALL32));
+                       }
+                       /* Flush only the local CPU. Other CPUs taking a fault
+                          will just end up here again
+                          This probably not needed and just paranoia. */
+                       __flush_tlb_one(address);
+                       err = 0;
                }
-               /* Flush only the local CPU. Other CPUs taking a fault
-                  will just end up here again */
-               __flush_tlb_one(address); 
-       } else
-               err = -ENOMEM; 
+       }
        spin_unlock(&mm->page_table_lock);
        return err;
 }