aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2006-12-06 20:14:01 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:01 -0500
commite5e3a0428968dcc1f9318ce1c941a918e99f8b84 (patch)
treefa2dcb620a22ba197371ac08944628993958ba1e
parente2764a1e306c986053a52b33748c33463cf888de (diff)
[PATCH] i386: remove default_ldt, and simplify ldt-setting.
This patch removes the default_ldt[] array, as it has been unused since iBCS stopped being supported. This means it is now possible to actually set an empty LDT segment. In order to deal with this, the set_ldt_desc/load_LDT pair has been replaced with a single set_ldt() operation which is responsible for both setting up the LDT descriptor in the GDT, and reloading the LDT register. If there are no LDT entries, the LDT register is loaded with a NULL descriptor. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de> Acked-by: Zachary Amsden <zach@vmware.com> Signed-off-by: Andrew Morton <akpm@osdl.org>
-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