Add hooks that the hypervisor can use to establish writable and non-writable
pages for LDT pages.  I made these parallel the page flags as defined in
include/linux/page-flags.h, since the flag mechanism is very similar to the
hypercall page flagging, and extended easily later to include PT, PD, PDP,
GDT, etc.

Patch-against: 2.6.13-rc5-mm1
Patch-keys: i386 ldt paravirt xen
Signed-off-by: Zachary Amsden <[EMAIL PROTECTED]>
Index: linux-2.6.13/arch/i386/kernel/ldt.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/ldt.c    2005-08-10 17:06:52.000000000 
-0700
+++ linux-2.6.13/arch/i386/kernel/ldt.c 2005-08-10 17:11:38.000000000 -0700
@@ -18,6 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
+#include <mach_pgalloc.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warning */
 static void flush_ldt(void *null)
@@ -59,16 +60,19 @@
 #ifdef CONFIG_SMP
                cpumask_t mask;
                preempt_disable();
+               SetPagesLDT(pc->ldt, (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE);
                load_LDT(pc);
                mask = cpumask_of_cpu(smp_processor_id());
                if (!cpus_equal(current->mm->cpu_vm_mask, mask))
                        smp_call_function(flush_ldt, NULL, 1, 1);
                preempt_enable();
 #else
+               SetPagesLDT(pc->ldt, (pc->size * LDT_ENTRY_SIZE) / PAGE_SIZE);
                load_LDT(pc);
 #endif
        }
        if (oldsize) {
+               ClearPagesLDT(oldldt, (oldsize * LDT_ENTRY_SIZE) / PAGE_SIZE);
                if (oldsize*LDT_ENTRY_SIZE > PAGE_SIZE)
                        vfree(oldldt);
                else
@@ -83,8 +87,10 @@
 
        down(&old->sem);
        err = alloc_ldt(new, 0, old->size, 0);
-       if (!err)
+       if (!err) {
                memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
+               SetPagesLDT(new->ldt, (new->size * LDT_ENTRY_SIZE) / PAGE_SIZE);
+       }
        up(&old->sem);
        return err;
 }
@@ -93,6 +99,7 @@
 {
        if (mm == current->active_mm)
                clear_LDT();
+       ClearPagesLDT(mm->context.ldt, (mm->context.size * LDT_ENTRY_SIZE) / 
PAGE_SIZE);
        if (mm->context.size*LDT_ENTRY_SIZE > PAGE_SIZE)
                vfree(mm->context.ldt);
        else
Index: linux-2.6.13/include/asm-i386/mach-default/mach_pgalloc.h
===================================================================
--- linux-2.6.13.orig/include/asm-i386/mach-default/mach_pgalloc.h      
2005-08-10 17:11:38.000000000 -0700
+++ linux-2.6.13/include/asm-i386/mach-default/mach_pgalloc.h   2005-08-10 
17:11:38.000000000 -0700
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_PGALLOC_H
+#define __ASM_MACH_PGALLOC_H
+
+#define SetPagesLDT(_va, _pages)
+#define ClearPagesLDT(_va, _pages)
+
+#endif
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to