diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2006-12-06 20:14:01 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:01 -0500 |
commit | e5e3a0428968dcc1f9318ce1c941a918e99f8b84 (patch) | |
tree | fa2dcb620a22ba197371ac08944628993958ba1e | |
parent | e2764a1e306c986053a52b33748c33463cf888de (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.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 |