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 |
