diff options
-rw-r--r-- | arch/i386/kernel/ldt.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/traps.c | 3 | ||||
-rw-r--r-- | include/asm-i386/desc.h | 50 | ||||
-rw-r--r-- | include/asm-i386/mmu_context.h | 4 |
4 files changed, 22 insertions, 39 deletions
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c index 445211eb2d57..b410e5fb034f 100644 --- a/arch/i386/kernel/ldt.c +++ b/arch/i386/kernel/ldt.c | |||
@@ -160,16 +160,14 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) | |||
160 | { | 160 | { |
161 | int err; | 161 | int err; |
162 | unsigned long size; | 162 | unsigned long size; |
163 | void *address; | ||
164 | 163 | ||
165 | err = 0; | 164 | err = 0; |
166 | address = &default_ldt[0]; | ||
167 | size = 5*sizeof(struct desc_struct); | 165 | size = 5*sizeof(struct desc_struct); |
168 | if (size > bytecount) | 166 | if (size > bytecount) |
169 | size = bytecount; | 167 | size = bytecount; |
170 | 168 | ||
171 | err = size; | 169 | err = size; |
172 | if (copy_to_user(ptr, address, size)) | 170 | if (clear_user(ptr, size)) |
173 | err = -EFAULT; | 171 | err = -EFAULT; |
174 | 172 | ||
175 | return err; | 173 | return err; |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 48ebfab661b7..56655ea8d98f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -61,9 +61,6 @@ int panic_on_unrecovered_nmi; | |||
61 | 61 | ||
62 | asmlinkage int system_call(void); | 62 | asmlinkage int system_call(void); |
63 | 63 | ||
64 | struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, | ||
65 | { 0, 0 }, { 0, 0 } }; | ||
66 | |||
67 | /* Do we ignore FPU interrupts ? */ | 64 | /* Do we ignore FPU interrupts ? */ |
68 | char ignore_fpu_irq = 0; | 65 | char ignore_fpu_irq = 0; |
69 | 66 | ||
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 5874ef119ffd..a0398f780ca1 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h | |||
@@ -33,11 +33,6 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | |||
33 | return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; | 33 | return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; |
34 | } | 34 | } |
35 | 35 | ||
36 | /* | ||
37 | * This is the ldt that every process will get unless we need | ||
38 | * something other than this. | ||
39 | */ | ||
40 | extern struct desc_struct default_ldt[]; | ||
41 | extern struct desc_struct idt_table[]; | 36 | extern struct desc_struct idt_table[]; |
42 | extern void set_intr_gate(unsigned int irq, void * addr); | 37 | extern void set_intr_gate(unsigned int irq, void * addr); |
43 | 38 | ||
@@ -65,7 +60,6 @@ static inline void pack_gate(__u32 *a, __u32 *b, | |||
65 | #define DESCTYPE_S 0x10 /* !system */ | 60 | #define DESCTYPE_S 0x10 /* !system */ |
66 | 61 | ||
67 | #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) | 62 | #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) |
68 | #define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)) | ||
69 | 63 | ||
70 | #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) | 64 | #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) |
71 | #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) | 65 | #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) |
@@ -115,13 +109,20 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo | |||
115 | write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); | 109 | write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); |
116 | } | 110 | } |
117 | 111 | ||
118 | static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) | 112 | static inline void set_ldt(void *addr, unsigned int entries) |
119 | { | 113 | { |
120 | __u32 a, b; | 114 | if (likely(entries == 0)) |
121 | pack_descriptor(&a, &b, (unsigned long)addr, | 115 | __asm__ __volatile__("lldt %w0"::"q" (0)); |
122 | entries * sizeof(struct desc_struct) - 1, | 116 | else { |
123 | DESCTYPE_LDT, 0); | 117 | unsigned cpu = smp_processor_id(); |
124 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); | 118 | __u32 a, b; |
119 | |||
120 | pack_descriptor(&a, &b, (unsigned long)addr, | ||
121 | entries * sizeof(struct desc_struct) - 1, | ||
122 | DESCTYPE_LDT, 0); | ||
123 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); | ||
124 | __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); | ||
125 | } | ||
125 | } | 126 | } |
126 | 127 | ||
127 | #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) | 128 | #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) |
@@ -153,35 +154,22 @@ static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entri | |||
153 | 154 | ||
154 | static inline void clear_LDT(void) | 155 | static inline void clear_LDT(void) |
155 | { | 156 | { |
156 | int cpu = get_cpu(); | 157 | set_ldt(NULL, 0); |
157 | |||
158 | set_ldt_desc(cpu, &default_ldt[0], 5); | ||
159 | load_LDT_desc(); | ||
160 | put_cpu(); | ||
161 | } | 158 | } |
162 | 159 | ||
163 | /* | 160 | /* |
164 | * load one particular LDT into the current CPU | 161 | * load one particular LDT into the current CPU |
165 | */ | 162 | */ |
166 | static inline void load_LDT_nolock(mm_context_t *pc, int cpu) | 163 | static inline void load_LDT_nolock(mm_context_t *pc) |
167 | { | 164 | { |
168 | void *segments = pc->ldt; | 165 | set_ldt(pc->ldt, pc->size); |
169 | int count = pc->size; | ||
170 | |||
171 | if (likely(!count)) { | ||
172 | segments = &default_ldt[0]; | ||
173 | count = 5; | ||
174 | } | ||
175 | |||
176 | set_ldt_desc(cpu, segments, count); | ||
177 | load_LDT_desc(); | ||
178 | } | 166 | } |
179 | 167 | ||
180 | static inline void load_LDT(mm_context_t *pc) | 168 | static inline void load_LDT(mm_context_t *pc) |
181 | { | 169 | { |
182 | int cpu = get_cpu(); | 170 | preempt_disable(); |
183 | load_LDT_nolock(pc, cpu); | 171 | load_LDT_nolock(pc); |
184 | put_cpu(); | 172 | preempt_enable(); |
185 | } | 173 | } |
186 | 174 | ||
187 | static inline unsigned long get_desc_base(unsigned long *desc) | 175 | static inline unsigned long get_desc_base(unsigned long *desc) |
diff --git a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h index 62b7bf184094..1b1495372c4d 100644 --- a/include/asm-i386/mmu_context.h +++ b/include/asm-i386/mmu_context.h | |||
@@ -44,7 +44,7 @@ static inline void switch_mm(struct mm_struct *prev, | |||
44 | * load the LDT, if the LDT is different: | 44 | * load the LDT, if the LDT is different: |
45 | */ | 45 | */ |
46 | if (unlikely(prev->context.ldt != next->context.ldt)) | 46 | if (unlikely(prev->context.ldt != next->context.ldt)) |
47 | load_LDT_nolock(&next->context, cpu); | 47 | load_LDT_nolock(&next->context); |
48 | } | 48 | } |
49 | #ifdef CONFIG_SMP | 49 | #ifdef CONFIG_SMP |
50 | else { | 50 | else { |
@@ -56,7 +56,7 @@ static inline void switch_mm(struct mm_struct *prev, | |||
56 | * tlb flush IPI delivery. We must reload %cr3. | 56 | * tlb flush IPI delivery. We must reload %cr3. |
57 | */ | 57 | */ |
58 | load_cr3(next->pgd); | 58 | load_cr3(next->pgd); |
59 | load_LDT_nolock(&next->context, cpu); | 59 | load_LDT_nolock(&next->context); |
60 | } | 60 | } |
61 | } | 61 | } |
62 | #endif | 62 | #endif |