diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-07-23 17:21:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-24 06:30:06 -0400 |
commit | 38ffbe66d59051fd9cfcfc8545f164700e2fa3bc (patch) | |
tree | 37e76db49cc86b3da550a62f36d101c7269d262e /arch/x86/kernel/ldt.c | |
parent | 338b9bb3adac0d2c5a1e180491d9b001d624c402 (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.c | 9 |
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) | |||
86 | static inline int copy_ldt(mm_context_t *new, mm_context_t *old) | 89 | static 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 |