aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/ldt.c4
-rw-r--r--arch/i386/kernel/traps.c3
-rw-r--r--include/asm-i386/desc.h50
-rw-r--r--include/asm-i386/mmu_context.h4
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
62asmlinkage int system_call(void); 62asmlinkage int system_call(void);
63 63
64struct 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 ? */
68char ignore_fpu_irq = 0; 65char 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 */
40extern struct desc_struct default_ldt[];
41extern struct desc_struct idt_table[]; 36extern struct desc_struct idt_table[];
42extern void set_intr_gate(unsigned int irq, void * addr); 37extern 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
118static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) 112static 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
154static inline void clear_LDT(void) 155static 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 */
166static inline void load_LDT_nolock(mm_context_t *pc, int cpu) 163static 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
180static inline void load_LDT(mm_context_t *pc) 168static 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
187static inline unsigned long get_desc_base(unsigned long *desc) 175static 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