]> err.no Git - linux-2.6/blobdiff - arch/x86/kernel/ldt.c
x86: use BOOTMEM_EXCLUSIVE on 32-bit
[linux-2.6] / arch / x86 / kernel / ldt.c
index a8cdca3615bf632afae851a75391a7862959f528..0224c3637c73e68b4566124dd5d825034bc8c07a 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/vmalloc.h>
-#include <linux/slab.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -36,11 +35,12 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
        if (mincount <= pc->size)
                return 0;
        oldsize = pc->size;
-       mincount = (mincount + 511) & (~511);
+       mincount = (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) &
+                       (~(PAGE_SIZE / LDT_ENTRY_SIZE - 1));
        if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
                newldt = vmalloc(mincount * LDT_ENTRY_SIZE);
        else
-               newldt = kmalloc(mincount * LDT_ENTRY_SIZE, GFP_KERNEL);
+               newldt = (void *)__get_free_page(GFP_KERNEL);
 
        if (!newldt)
                return -ENOMEM;
@@ -78,7 +78,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
                if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
                        vfree(oldldt);
                else
-                       kfree(oldldt);
+                       put_page(virt_to_page(oldldt));
        }
        return 0;
 }
@@ -129,7 +129,7 @@ void destroy_context(struct mm_struct *mm)
                if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
                        vfree(mm->context.ldt);
                else
-                       kfree(mm->context.ldt);
+                       put_page(virt_to_page(mm->context.ldt));
                mm->context.size = 0;
        }
 }
@@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount)
 static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
 {
        struct mm_struct *mm = current->mm;
-       __u32 entry_1, entry_2;
+       struct desc_struct ldt;
        int error;
        struct user_desc ldt_info;
 
@@ -218,21 +218,18 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
        /* Allow LDTs to be cleared by the user. */
        if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
                if (oldmode || LDT_empty(&ldt_info)) {
-                       entry_1 = 0;
-                       entry_2 = 0;
+                       memset(&ldt, 0, sizeof(ldt));
                        goto install;
                }
        }
 
-       entry_1 = LDT_entry_a(&ldt_info);
-       entry_2 = LDT_entry_b(&ldt_info);
+       fill_ldt(&ldt, &ldt_info);
        if (oldmode)
-               entry_2 &= ~(1 << 20);
+               ldt.avl = 0;
 
        /* Install the new entry ...  */
 install:
-       write_ldt_entry(mm->context.ldt, ldt_info.entry_number, entry_1,
-                       entry_2);
+       write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt);
        error = 0;
 
 out_unlock: