]> err.no Git - linux-2.6/commitdiff
x86: adjust/fix LDT handling for Xen
authorJan Beulich <jbeulich@novell.com>
Wed, 30 Jan 2008 12:33:14 +0000 (13:33 +0100)
committerIngo Molnar <mingo@elte.hu>
Wed, 30 Jan 2008 12:33:14 +0000 (13:33 +0100)
Based on patch from Jan Beulich <jbeulich@novell.com>.

Don't rely on kmalloc(PAGE_SIZE) returning PAGE_SIZE aligned memory
(Xen requires GDT *and* LDT to be page-aligned). Using the page
allocator interface also removes the (albeit small) slab allocator
overhead. The same change being done for 64-bits for consistency.

Further, the Xen hypercall interface expects the LDT address to be
virtual, not machine.

[ Adjusted to unified ldt.c - Jeremy ]

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Acked-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/kernel/ldt.c
arch/x86/xen/enlighten.c

index b8ef46270e246d1d77a39777bb27292fc30a1d66..8a7660c8394a5a2ae2362e6d3d4ec032d5def37e 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>
@@ -40,7 +39,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
        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 +77,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 +128,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;
        }
 }
index 72dd14d0685ce0539f98dd75ff0b65e6091ec0e4..845b4fd944632afc1200c9640df4c9d5ed0c4f94 100644 (file)
@@ -275,19 +275,12 @@ static unsigned long xen_store_tr(void)
 
 static void xen_set_ldt(const void *addr, unsigned entries)
 {
-       unsigned long linear_addr = (unsigned long)addr;
        struct mmuext_op *op;
        struct multicall_space mcs = xen_mc_entry(sizeof(*op));
 
        op = mcs.args;
        op->cmd = MMUEXT_SET_LDT;
-       if (linear_addr) {
-               /* ldt my be vmalloced, use arbitrary_virt_to_machine */
-               xmaddr_t maddr;
-               maddr = arbitrary_virt_to_machine((unsigned long)addr);
-               linear_addr = (unsigned long)maddr.maddr;
-       }
-       op->arg1.linear_addr = linear_addr;
+       op->arg1.linear_addr = (unsigned long)addr;
        op->arg2.nr_ents = entries;
 
        MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);