diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-01-28 01:51:23 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-01-28 02:36:24 +0100 |
commit | 28d83087776ebdad43a11fa3e687859462de4542 (patch) | |
tree | e86cecc7ac4dfd13c4eb1500078abe8283fbe7f7 | |
parent | 338d9ca7981f25099d99d280b0dd3af590d65763 (diff) |
Add initial code for disabling PV descriptors
* xen/configfrag.ac (--disable-pv-descriptors): Add option
* i386/xen/xen_boothdr.S (XEN_ELFNOTE_FEATURES) [!MACH_PV_DESCRIPTORS]: Add
writable_descriptor_tables.
* i386/i386/gdt.c: Turn appropriate MACH_XEN/MACH_HYP tests into
MACH_PV_DESCRIPTORS tests.
* i386/i386/gdt.h: Likewise.
* i386/i386/i386asm.sym: Likewise.
* i386/i386/idt.c: Likewise.
* i386/i386/idt_inittab.S: Likewise.
* i386/i386/ldt.c: Likewise.
* i386/i386/pcb.c: Likewise.
* i386/i386/seg.h: Likewise.
* i386/i386/user_ldt.c: Likewise.
* i386/i386/user_ldt.h: Likewise.
-rw-r--r-- | i386/i386/gdt.c | 14 | ||||
-rw-r--r-- | i386/i386/gdt.h | 6 | ||||
-rw-r--r-- | i386/i386/i386asm.sym | 4 | ||||
-rw-r--r-- | i386/i386/idt.c | 6 | ||||
-rw-r--r-- | i386/i386/idt_inittab.S | 8 | ||||
-rw-r--r-- | i386/i386/ldt.c | 16 | ||||
-rw-r--r-- | i386/i386/pcb.c | 18 | ||||
-rw-r--r-- | i386/i386/seg.h | 12 | ||||
-rw-r--r-- | i386/i386/user_ldt.c | 18 | ||||
-rw-r--r-- | i386/i386/user_ldt.h | 4 | ||||
-rw-r--r-- | i386/xen/xen_boothdr.S | 8 | ||||
-rw-r--r-- | xen/configfrag.ac | 14 |
12 files changed, 73 insertions, 55 deletions
diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c index f26a50c..b686faa 100644 --- a/i386/i386/gdt.c +++ b/i386/i386/gdt.c @@ -39,10 +39,10 @@ #include "seg.h" #include "gdt.h" -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS /* It is actually defined in xen_boothdr.S */ extern -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ struct real_descriptor gdt[GDTSZ]; void @@ -57,14 +57,14 @@ gdt_init() LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, LINEAR_MAX_KERNEL_ADDRESS - (LINEAR_MIN_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) - 1, ACC_PL_K|ACC_DATA_W, SZ_32); -#ifndef MACH_HYP +#ifndef MACH_PV_DESCRIPTORS fill_gdt_descriptor(LINEAR_DS, 0, 0xffffffff, ACC_PL_K|ACC_DATA_W, SZ_32); -#endif /* MACH_HYP */ +#endif /* MACH_PV_DESCRIPTORS */ -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS unsigned long frame = kv_to_mfn(gdt); pmap_set_page_readonly(gdt); if (hyp_set_gdt(kv_to_la(&frame), GDTSZ)) @@ -75,7 +75,7 @@ gdt_init() if (hyp_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify)) panic("couldn't set 4gb segments vm assist notify"); #endif -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ /* Load the new GDT. */ { struct pseudo_descriptor pdesc; @@ -84,7 +84,7 @@ gdt_init() pdesc.linear_base = kvtolin(&gdt); lgdt(&pdesc); } -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* Reload all the segment registers from the new GDT. We must load ds and es with 0 before loading them with KERNEL_DS diff --git a/i386/i386/gdt.h b/i386/i386/gdt.h index 41ace79..788f48a 100644 --- a/i386/i386/gdt.h +++ b/i386/i386/gdt.h @@ -40,14 +40,14 @@ */ #define KERNEL_CS (0x08 | KERNEL_RING) /* kernel code */ #define KERNEL_DS (0x10 | KERNEL_RING) /* kernel data */ -#ifndef MACH_XEN +#ifndef MACH_PV_DESCRIPTORS #define KERNEL_LDT 0x18 /* master LDT */ -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ #define KERNEL_TSS 0x20 /* master TSS (uniprocessor) */ #define USER_LDT 0x28 /* place for per-thread LDT */ #define USER_TSS 0x30 /* place for per-thread TSS that holds IO bitmap */ -#ifndef MACH_HYP +#ifndef MACH_PV_DESCRIPTORS #define LINEAR_DS 0x38 /* linear mapping */ #endif /* MACH_HYP */ /* 0x40 was USER_FPREGS, now free */ diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym index c4e4648..bcee28f 100644 --- a/i386/i386/i386asm.sym +++ b/i386/i386/i386asm.sym @@ -124,9 +124,9 @@ expr KERNEL_RING expr KERNEL_CS expr KERNEL_DS expr KERNEL_TSS -#ifndef MACH_XEN +#ifndef MACH_PV_DESCRIPTORS expr KERNEL_LDT -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ expr (VM_MIN_KERNEL_ADDRESS>>PDESHIFT)*sizeof(pt_entry_t) KERNELBASEPDE diff --git a/i386/i386/idt.c b/i386/i386/idt.c index b5e3d08..882764f 100644 --- a/i386/i386/idt.c +++ b/i386/i386/idt.c @@ -38,10 +38,10 @@ extern struct idt_init_entry idt_inittab[]; void idt_init() { -#ifdef MACH_HYP +#ifdef MACH_PV_DESCRIPTORS if (hyp_set_trap_table(kvtolin(idt_inittab))) panic("couldn't set trap table\n"); -#else /* MACH_HYP */ +#else /* MACH_PV_DESCRIPTORS */ struct idt_init_entry *iie = idt_inittab; /* Initialize the exception vectors from the idt_inittab. */ @@ -59,6 +59,6 @@ void idt_init() pdesc.linear_base = kvtolin(&idt); lidt(&pdesc); } -#endif /* MACH_HYP */ +#endif /* MACH_PV_DESCRIPTORS */ } diff --git a/i386/i386/idt_inittab.S b/i386/i386/idt_inittab.S index 63e554b..36093b6 100644 --- a/i386/i386/idt_inittab.S +++ b/i386/i386/idt_inittab.S @@ -39,7 +39,7 @@ ENTRY(idt_inittab) /* * Interrupt descriptor table and code vectors for it. */ -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS #define IDT_ENTRY(n,entry,type) \ .data 2 ;\ .byte n ;\ @@ -47,14 +47,14 @@ ENTRY(idt_inittab) .word KERNEL_CS ;\ .long entry ;\ .text -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ #define IDT_ENTRY(n,entry,type) \ .data 2 ;\ .long entry ;\ .word n ;\ .word type ;\ .text -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* * No error code. Clear error code and push trap number. @@ -108,7 +108,7 @@ EXCEP_SPC(0x0b,t_segnp) EXCEP_ERR(0x0c,t_stack_fault) EXCEP_SPC(0x0d,t_gen_prot) EXCEP_SPC(0x0e,t_page_fault) -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS EXCEP_ERR(0x0f,t_trap_0f) #else EXCEPTION(0x0f,t_trap_0f) diff --git a/i386/i386/ldt.c b/i386/i386/ldt.c index 0ef7a8c..58af94b 100644 --- a/i386/i386/ldt.c +++ b/i386/i386/ldt.c @@ -39,23 +39,23 @@ extern int syscall(); -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS /* It is actually defined in xen_boothdr.S */ extern -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ struct real_descriptor ldt[LDTSZ]; void ldt_init() { -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS pmap_set_page_readwrite(ldt); -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ /* Initialize the master LDT descriptor in the GDT. */ fill_gdt_descriptor(KERNEL_LDT, kvtolin(&ldt), sizeof(ldt)-1, ACC_PL_K|ACC_LDT, 0); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* Initialize the LDT descriptors. */ fill_ldt_gate(USER_SCALL, @@ -72,9 +72,9 @@ ldt_init() ACC_PL_U|ACC_DATA_W, SZ_32); /* Activate the LDT. */ -#ifdef MACH_HYP +#ifdef MACH_PV_DESCRIPTORS hyp_set_ldt(&ldt, LDTSZ); -#else /* MACH_HYP */ +#else /* MACH_PV_DESCRIPTORS */ lldt(KERNEL_LDT); -#endif /* MACH_HYP */ +#endif /* MACH_PV_DESCRIPTORS */ } diff --git a/i386/i386/pcb.c b/i386/i386/pcb.c index 362d990..8d37d69 100644 --- a/i386/i386/pcb.c +++ b/i386/i386/pcb.c @@ -173,28 +173,28 @@ void switch_ktss(pcb) /* * Use system LDT. */ -#ifdef MACH_HYP +#ifdef MACH_PV_DESCRIPTORS hyp_set_ldt(&ldt, LDTSZ); -#else /* MACH_HYP */ +#else /* MACH_PV_DESCRIPTORS */ set_ldt(KERNEL_LDT); -#endif /* MACH_HYP */ +#endif /* MACH_PV_DESCRIPTORS */ } else { /* * Thread has its own LDT. */ -#ifdef MACH_HYP +#ifdef MACH_PV_DESCRIPTORS hyp_set_ldt(tldt->ldt, (tldt->desc.limit_low|(tldt->desc.limit_high<<16)) / sizeof(struct real_descriptor)); -#else /* MACH_HYP */ +#else /* MACH_PV_DESCRIPTORS */ *gdt_desc_p(mycpu,USER_LDT) = tldt->desc; set_ldt(USER_LDT); -#endif /* MACH_HYP */ +#endif /* MACH_PV_DESCRIPTORS */ } } -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS { int i; for (i=0; i < USER_GDT_SLOTS; i++) { @@ -206,14 +206,14 @@ void switch_ktss(pcb) } } } -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ /* Copy in the per-thread GDT slots. No reloading is necessary because just restoring the segment registers on the way back to user mode reloads the shadow registers from the in-memory GDT. */ memcpy (gdt_desc_p (mycpu, USER_GDT), pcb->ims.user_gdt, sizeof pcb->ims.user_gdt); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* * Load the floating-point context, if necessary. diff --git a/i386/i386/seg.h b/i386/i386/seg.h index a7f6573..fe7acc1 100644 --- a/i386/i386/seg.h +++ b/i386/i386/seg.h @@ -161,12 +161,12 @@ MACH_INLINE void fill_descriptor(struct real_descriptor *_desc, unsigned base, unsigned limit, unsigned char access, unsigned char sizebits) { - /* TODO: when !MACH_XEN, setting desc and just memcpy isn't simpler actually */ -#ifdef MACH_XEN + /* TODO: when !MACH_PV_DESCRIPTORS, setting desc and just memcpy isn't simpler actually */ +#ifdef MACH_PV_DESCRIPTORS struct real_descriptor __desc, *desc = &__desc; -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ struct real_descriptor *desc = _desc; -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ if (limit > 0xfffff) { limit >>= 12; @@ -179,10 +179,10 @@ fill_descriptor(struct real_descriptor *_desc, unsigned base, unsigned limit, desc->limit_high = limit >> 16; desc->granularity = sizebits; desc->base_high = base >> 24; -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS if (hyp_do_update_descriptor(kv_to_ma(_desc), *(uint64_t*)desc)) panic("couldn't update descriptor(%p to %08lx%08lx)\n", (vm_offset_t) kv_to_ma(_desc), *(((unsigned long*)desc)+1), *(unsigned long *)desc); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ } /* Fill a gate with particular values. */ diff --git a/i386/i386/user_ldt.c b/i386/i386/user_ldt.c index dfe6b1e..70ef7cb 100644 --- a/i386/i386/user_ldt.c +++ b/i386/i386/user_ldt.c @@ -196,17 +196,17 @@ i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline) if (new_ldt == 0) { simple_unlock(&pcb->lock); -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS /* LDT needs to be aligned on a page */ vm_offset_t alloc = kalloc(ldt_size_needed + PAGE_SIZE + offsetof(struct user_ldt, ldt)); new_ldt = (user_ldt_t) (round_page((alloc + offsetof(struct user_ldt, ldt))) - offsetof(struct user_ldt, ldt)); new_ldt->alloc = alloc; -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ new_ldt = (user_ldt_t) kalloc(ldt_size_needed + sizeof(struct real_descriptor)); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* * Build a descriptor that describes the * LDT itself @@ -272,7 +272,7 @@ i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline) simple_unlock(&pcb->lock); if (new_ldt) -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS { int i; for (i=0; i<(new_ldt->desc.limit_low + 1)/sizeof(struct real_descriptor); i+=PAGE_SIZE/sizeof(struct real_descriptor)) @@ -280,11 +280,11 @@ i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline) kfree(new_ldt->alloc, new_ldt->desc.limit_low + 1 + PAGE_SIZE + offsetof(struct user_ldt, ldt)); } -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ kfree((vm_offset_t)new_ldt, new_ldt->desc.limit_low + 1 + sizeof(struct real_descriptor)); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ /* * Free the descriptor list, if it was @@ -417,17 +417,17 @@ void user_ldt_free(user_ldt) user_ldt_t user_ldt; { -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS int i; for (i=0; i<(user_ldt->desc.limit_low + 1)/sizeof(struct real_descriptor); i+=PAGE_SIZE/sizeof(struct real_descriptor)) pmap_set_page_readwrite(&user_ldt->ldt[i]); kfree(user_ldt->alloc, user_ldt->desc.limit_low + 1 + PAGE_SIZE + offsetof(struct user_ldt, ldt)); -#else /* MACH_XEN */ +#else /* MACH_PV_DESCRIPTORS */ kfree((vm_offset_t)user_ldt, user_ldt->desc.limit_low + 1 + sizeof(struct real_descriptor)); -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ } diff --git a/i386/i386/user_ldt.h b/i386/i386/user_ldt.h index 8d16ed8..6c6c858 100644 --- a/i386/i386/user_ldt.h +++ b/i386/i386/user_ldt.h @@ -36,9 +36,9 @@ #include <i386/seg.h> struct user_ldt { -#ifdef MACH_XEN +#ifdef MACH_PV_DESCRIPTORS vm_offset_t alloc; /* allocation before alignment */ -#endif /* MACH_XEN */ +#endif /* MACH_PV_DESCRIPTORS */ struct real_descriptor desc; /* descriptor for self */ struct real_descriptor ldt[1]; /* descriptor table (variable) */ }; diff --git a/i386/xen/xen_boothdr.S b/i386/xen/xen_boothdr.S index eacf0d8..4e2fb51 100644 --- a/i386/xen/xen_boothdr.S +++ b/i386/xen/xen_boothdr.S @@ -36,6 +36,9 @@ #else /* MACH_PSEUDO_PHYS */ .ascii ",FEATURES=!auto_translated_physmap" #endif +#ifndef MACH_PV_DESCRIPTORS + .ascii "|writable_descriptor_tables" +#endif /* MACH_PV_DESCRIPTORS */ .byte 0 /* Macro taken from linux/include/linux/elfnote.h */ @@ -68,8 +71,11 @@ #ifdef MACH_PSEUDO_PHYS "pae_pgdir_above_4gb" #else /* MACH_PSEUDO_PHYS */ - "!auto_translated_physmap|" + "!auto_translated_physmap" #endif +#ifndef MACH_PV_DESCRIPTORS + "|writable_descriptor_tables" +#endif /* MACH_PV_DESCRIPTORS */ ) #include <mach/machine/asm.h> diff --git a/xen/configfrag.ac b/xen/configfrag.ac index eb68996..d0705a4 100644 --- a/xen/configfrag.ac +++ b/xen/configfrag.ac @@ -25,8 +25,10 @@ dnl 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. AC_DEFINE([MACH_HYP], [], [be a hypervisor guest]) AM_CONDITIONAL([PLATFORM_xen], [true]) +dnl These are experimental + AC_ARG_ENABLE([pseudo-phys], - AS_HELP_STRING([--enable-pseudo-phys], [Pseudo physical support])) + AS_HELP_STRING([--disable-pseudo-phys], [Pseudo physical pages support])) [if [ x"$enable_pseudo_phys" = xno ]; then] AM_CONDITIONAL([enable_pseudo_phys], [false]) [else] @@ -34,9 +36,19 @@ dnl 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. AM_CONDITIONAL([enable_pseudo_phys], [true]) [fi] + AC_ARG_ENABLE([pv-descriptors], + AS_HELP_STRING([--disable-pv-descriptors], [Paravirtualized segment descriptors support])) + [if [ x"$enable_pv_descriptors" = xno ]; then] + AM_CONDITIONAL([enable_pv_descriptors], [false]) + [else] + AC_DEFINE([MACH_PV_DESCRIPTORS], [], [Enable paravirtualized segment descriptors support]) + AM_CONDITIONAL([enable_pv_descriptors], [true]) + [fi] + [else] AM_CONDITIONAL([PLATFORM_xen], [false]) AM_CONDITIONAL([enable_pseudo_phys], [false]) + AM_CONDITIONAL([enable_pv_descriptors], [false]) [fi] dnl Local Variables: |