summaryrefslogtreecommitdiff
path: root/i386/i386/user_ldt.c
diff options
context:
space:
mode:
Diffstat (limited to 'i386/i386/user_ldt.c')
-rw-r--r--i386/i386/user_ldt.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/i386/i386/user_ldt.c b/i386/i386/user_ldt.c
index 942ad07..dfe6b1e 100644
--- a/i386/i386/user_ldt.c
+++ b/i386/i386/user_ldt.c
@@ -39,6 +39,7 @@
#include <i386/seg.h>
#include <i386/thread.h>
#include <i386/user_ldt.h>
+#include <stddef.h>
#include "ldt.h"
#include "vm_param.h"
@@ -195,9 +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
+ /* 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 */
new_ldt = (user_ldt_t)
kalloc(ldt_size_needed
+ sizeof(struct real_descriptor));
+#endif /* MACH_XEN */
/*
* Build a descriptor that describes the
* LDT itself
@@ -263,9 +272,19 @@ i386_set_ldt(thread, first_selector, desc_list, count, desc_list_inline)
simple_unlock(&pcb->lock);
if (new_ldt)
+#ifdef MACH_XEN
+ {
+ int i;
+ for (i=0; i<(new_ldt->desc.limit_low + 1)/sizeof(struct real_descriptor); i+=PAGE_SIZE/sizeof(struct real_descriptor))
+ pmap_set_page_readwrite(&new_ldt->ldt[i]);
+ kfree(new_ldt->alloc, new_ldt->desc.limit_low + 1
+ + PAGE_SIZE + offsetof(struct user_ldt, ldt));
+ }
+#else /* MACH_XEN */
kfree((vm_offset_t)new_ldt,
new_ldt->desc.limit_low + 1
+ sizeof(struct real_descriptor));
+#endif /* MACH_XEN */
/*
* Free the descriptor list, if it was
@@ -398,9 +417,17 @@ void
user_ldt_free(user_ldt)
user_ldt_t user_ldt;
{
+#ifdef MACH_XEN
+ 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 */
kfree((vm_offset_t)user_ldt,
user_ldt->desc.limit_low + 1
+ sizeof(struct real_descriptor));
+#endif /* MACH_XEN */
}