summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2013-01-28 01:51:23 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-01-28 02:36:24 +0100
commit28d83087776ebdad43a11fa3e687859462de4542 (patch)
treee86cecc7ac4dfd13c4eb1500078abe8283fbe7f7
parent338d9ca7981f25099d99d280b0dd3af590d65763 (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.c14
-rw-r--r--i386/i386/gdt.h6
-rw-r--r--i386/i386/i386asm.sym4
-rw-r--r--i386/i386/idt.c6
-rw-r--r--i386/i386/idt_inittab.S8
-rw-r--r--i386/i386/ldt.c16
-rw-r--r--i386/i386/pcb.c18
-rw-r--r--i386/i386/seg.h12
-rw-r--r--i386/i386/user_ldt.c18
-rw-r--r--i386/i386/user_ldt.h4
-rw-r--r--i386/xen/xen_boothdr.S8
-rw-r--r--xen/configfrag.ac14
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: