diff options
Diffstat (limited to 'arch/x86/kernel/ldt.c')
-rw-r--r-- | arch/x86/kernel/ldt.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index b68e21f06f4f..eee32b43fee3 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/ldt.h> | 18 | #include <asm/ldt.h> |
19 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
20 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
21 | #include <asm/syscalls.h> | ||
21 | 22 | ||
22 | #ifdef CONFIG_SMP | 23 | #ifdef CONFIG_SMP |
23 | static void flush_ldt(void *current_mm) | 24 | static void flush_ldt(void *current_mm) |
@@ -51,6 +52,8 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) | |||
51 | memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, | 52 | memset(newldt + oldsize * LDT_ENTRY_SIZE, 0, |
52 | (mincount - oldsize) * LDT_ENTRY_SIZE); | 53 | (mincount - oldsize) * LDT_ENTRY_SIZE); |
53 | 54 | ||
55 | paravirt_alloc_ldt(newldt, mincount); | ||
56 | |||
54 | #ifdef CONFIG_X86_64 | 57 | #ifdef CONFIG_X86_64 |
55 | /* CHECKME: Do we really need this ? */ | 58 | /* CHECKME: Do we really need this ? */ |
56 | wmb(); | 59 | wmb(); |
@@ -73,6 +76,7 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) | |||
73 | #endif | 76 | #endif |
74 | } | 77 | } |
75 | if (oldsize) { | 78 | if (oldsize) { |
79 | paravirt_free_ldt(oldldt, oldsize); | ||
76 | if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) | 80 | if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE) |
77 | vfree(oldldt); | 81 | vfree(oldldt); |
78 | else | 82 | else |
@@ -84,10 +88,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) | |||
84 | static inline int copy_ldt(mm_context_t *new, mm_context_t *old) | 88 | static inline int copy_ldt(mm_context_t *new, mm_context_t *old) |
85 | { | 89 | { |
86 | int err = alloc_ldt(new, old->size, 0); | 90 | int err = alloc_ldt(new, old->size, 0); |
91 | int i; | ||
87 | 92 | ||
88 | if (err < 0) | 93 | if (err < 0) |
89 | return err; | 94 | return err; |
90 | memcpy(new->ldt, old->ldt, old->size * LDT_ENTRY_SIZE); | 95 | |
96 | for(i = 0; i < old->size; i++) | ||
97 | write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE); | ||
91 | return 0; | 98 | return 0; |
92 | } | 99 | } |
93 | 100 | ||
@@ -124,6 +131,7 @@ void destroy_context(struct mm_struct *mm) | |||
124 | if (mm == current->active_mm) | 131 | if (mm == current->active_mm) |
125 | clear_LDT(); | 132 | clear_LDT(); |
126 | #endif | 133 | #endif |
134 | paravirt_free_ldt(mm->context.ldt, mm->context.size); | ||
127 | if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) | 135 | if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE) |
128 | vfree(mm->context.ldt); | 136 | vfree(mm->context.ldt); |
129 | else | 137 | else |