x86/paravirt/xen: properly fill out the ldt ops

LTP testing showed that Xen does not properly implement
sys_modify_ldt().  This patch does the final little bits needed to
make the ldt work properly.

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 9ff6e3c..06219e6 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -325,6 +325,26 @@
 	return 0;
 }
 
+static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
+{
+	unsigned pages = roundup(entries * LDT_ENTRY_SIZE, PAGE_SIZE);
+	void *v = ldt;
+	int i;
+
+	for(i = 0; i < pages; i += PAGE_SIZE)
+		make_lowmem_page_readonly(v + i);
+}
+
+static void xen_free_ldt(struct desc_struct *ldt, unsigned entries)
+{
+	unsigned pages = roundup(entries * LDT_ENTRY_SIZE, PAGE_SIZE);
+	void *v = ldt;
+	int i;
+
+	for(i = 0; i < pages; i += PAGE_SIZE)
+		make_lowmem_page_readwrite(v + i);
+}
+
 static void xen_set_ldt(const void *addr, unsigned entries)
 {
 	struct mmuext_op *op;
@@ -1220,6 +1240,9 @@
 	.load_gs_index = xen_load_gs_index,
 #endif
 
+	.alloc_ldt = xen_alloc_ldt,
+	.free_ldt = xen_free_ldt,
+
 	.store_gdt = native_store_gdt,
 	.store_idt = native_store_idt,
 	.store_tr = xen_store_tr,