aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ldt.c
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2008-07-23 17:21:18 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-24 06:30:06 -0400
commit38ffbe66d59051fd9cfcfc8545f164700e2fa3bc (patch)
tree37e76db49cc86b3da550a62f36d101c7269d262e /arch/x86/kernel/ldt.c
parent338b9bb3adac0d2c5a1e180491d9b001d624c402 (diff)
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>
Diffstat (limited to 'arch/x86/kernel/ldt.c')
-rw-r--r--arch/x86/kernel/ldt.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 3fee2aa50f3f..4895e0634d22 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -51,6 +51,8 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
51 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, 51 memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
52 (mincount - oldsize) * LDT_ENTRY_SIZE); 52 (mincount - oldsize) * LDT_ENTRY_SIZE);
53 53
54 paravirt_alloc_ldt(newldt, mincount);
55
54#ifdef CONFIG_X86_64 56#ifdef CONFIG_X86_64
55 /* CHECKME: Do we really need this ? */ 57 /* CHECKME: Do we really need this ? */
56 wmb(); 58 wmb();
@@ -75,6 +77,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
75#endif 77#endif
76 } 78 }
77 if (oldsize) { 79 if (oldsize) {
80 paravirt_free_ldt(oldldt, oldsize);
78 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) 81 if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
79 vfree(oldldt); 82 vfree(oldldt);
80 else 83 else
@@ -86,10 +89,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
86static inline int copy_ldt(mm_context_t *new, mm_context_t *old) 89static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
87{ 90{
88 int err = alloc_ldt(new, old->size, 0); 91 int err = alloc_ldt(new, old->size, 0);
92 int i;
89 93
90 if (err < 0) 94 if (err < 0)
91 return err; 95 return err;
92 memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE); 96
97 for(i = 0; i < old->size; i++)
98 write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
93 return 0; 99 return 0;
94} 100}
95 101
@@ -126,6 +132,7 @@ void destroy_context(struct mm_struct *mm)
126 if (mm == current->active_mm) 132 if (mm == current->active_mm)
127 clear_LDT(); 133 clear_LDT();
128#endif 134#endif
135 paravirt_free_ldt(mm->context.ldt, mm->context.size);
129 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) 136 if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
130 vfree(mm->context.ldt); 137 vfree(mm->context.ldt);
131 else 138 else