diff options
Diffstat (limited to 'include/asm-i386/desc.h')
-rw-r--r-- | include/asm-i386/desc.h | 95 |
1 files changed, 55 insertions, 40 deletions
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index 5874ef119ffd..f398cc456448 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #include <asm/ldt.h> | 4 | #include <asm/ldt.h> |
5 | #include <asm/segment.h> | 5 | #include <asm/segment.h> |
6 | 6 | ||
7 | #define CPU_16BIT_STACK_SIZE 1024 | ||
8 | |||
9 | #ifndef __ASSEMBLY__ | 7 | #ifndef __ASSEMBLY__ |
10 | 8 | ||
11 | #include <linux/preempt.h> | 9 | #include <linux/preempt.h> |
@@ -16,8 +14,6 @@ | |||
16 | 14 | ||
17 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | 15 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; |
18 | 16 | ||
19 | DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | ||
20 | |||
21 | struct Xgt_desc_struct { | 17 | struct Xgt_desc_struct { |
22 | unsigned short size; | 18 | unsigned short size; |
23 | unsigned long address __attribute__((packed)); | 19 | unsigned long address __attribute__((packed)); |
@@ -33,11 +29,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; | 29 | return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; |
34 | } | 30 | } |
35 | 31 | ||
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[]; | 32 | extern struct desc_struct idt_table[]; |
42 | extern void set_intr_gate(unsigned int irq, void * addr); | 33 | extern void set_intr_gate(unsigned int irq, void * addr); |
43 | 34 | ||
@@ -64,8 +55,10 @@ static inline void pack_gate(__u32 *a, __u32 *b, | |||
64 | #define DESCTYPE_DPL3 0x60 /* DPL-3 */ | 55 | #define DESCTYPE_DPL3 0x60 /* DPL-3 */ |
65 | #define DESCTYPE_S 0x10 /* !system */ | 56 | #define DESCTYPE_S 0x10 /* !system */ |
66 | 57 | ||
58 | #ifdef CONFIG_PARAVIRT | ||
59 | #include <asm/paravirt.h> | ||
60 | #else | ||
67 | #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) | 61 | #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 | 62 | ||
70 | #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) | 63 | #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) |
71 | #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) | 64 | #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) |
@@ -88,6 +81,10 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) | |||
88 | #undef C | 81 | #undef C |
89 | } | 82 | } |
90 | 83 | ||
84 | #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | ||
85 | #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | ||
86 | #define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | ||
87 | |||
91 | static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) | 88 | static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) |
92 | { | 89 | { |
93 | __u32 *lp = (__u32 *)((char *)dt + entry*8); | 90 | __u32 *lp = (__u32 *)((char *)dt + entry*8); |
@@ -95,9 +92,25 @@ static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entr | |||
95 | *(lp+1) = entry_b; | 92 | *(lp+1) = entry_b; |
96 | } | 93 | } |
97 | 94 | ||
98 | #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | 95 | #define set_ldt native_set_ldt |
99 | #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | 96 | #endif /* CONFIG_PARAVIRT */ |
100 | #define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) | 97 | |
98 | static inline fastcall void native_set_ldt(const void *addr, | ||
99 | unsigned int entries) | ||
100 | { | ||
101 | if (likely(entries == 0)) | ||
102 | __asm__ __volatile__("lldt %w0"::"q" (0)); | ||
103 | else { | ||
104 | unsigned cpu = smp_processor_id(); | ||
105 | __u32 a, b; | ||
106 | |||
107 | pack_descriptor(&a, &b, (unsigned long)addr, | ||
108 | entries * sizeof(struct desc_struct) - 1, | ||
109 | DESCTYPE_LDT, 0); | ||
110 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); | ||
111 | __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); | ||
112 | } | ||
113 | } | ||
101 | 114 | ||
102 | static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) | 115 | static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) |
103 | { | 116 | { |
@@ -115,14 +128,6 @@ 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); | 128 | write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); |
116 | } | 129 | } |
117 | 130 | ||
118 | static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) | ||
119 | { | ||
120 | __u32 a, b; | ||
121 | pack_descriptor(&a, &b, (unsigned long)addr, | ||
122 | entries * sizeof(struct desc_struct) - 1, | ||
123 | DESCTYPE_LDT, 0); | ||
124 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); | ||
125 | } | ||
126 | 131 | ||
127 | #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) | 132 | #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) |
128 | 133 | ||
@@ -153,35 +158,22 @@ static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entri | |||
153 | 158 | ||
154 | static inline void clear_LDT(void) | 159 | static inline void clear_LDT(void) |
155 | { | 160 | { |
156 | int cpu = get_cpu(); | 161 | set_ldt(NULL, 0); |
157 | |||
158 | set_ldt_desc(cpu, &default_ldt[0], 5); | ||
159 | load_LDT_desc(); | ||
160 | put_cpu(); | ||
161 | } | 162 | } |
162 | 163 | ||
163 | /* | 164 | /* |
164 | * load one particular LDT into the current CPU | 165 | * load one particular LDT into the current CPU |
165 | */ | 166 | */ |
166 | static inline void load_LDT_nolock(mm_context_t *pc, int cpu) | 167 | static inline void load_LDT_nolock(mm_context_t *pc) |
167 | { | 168 | { |
168 | void *segments = pc->ldt; | 169 | 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 | } | 170 | } |
179 | 171 | ||
180 | static inline void load_LDT(mm_context_t *pc) | 172 | static inline void load_LDT(mm_context_t *pc) |
181 | { | 173 | { |
182 | int cpu = get_cpu(); | 174 | preempt_disable(); |
183 | load_LDT_nolock(pc, cpu); | 175 | load_LDT_nolock(pc); |
184 | put_cpu(); | 176 | preempt_enable(); |
185 | } | 177 | } |
186 | 178 | ||
187 | static inline unsigned long get_desc_base(unsigned long *desc) | 179 | static inline unsigned long get_desc_base(unsigned long *desc) |
@@ -193,6 +185,29 @@ static inline unsigned long get_desc_base(unsigned long *desc) | |||
193 | return base; | 185 | return base; |
194 | } | 186 | } |
195 | 187 | ||
188 | #else /* __ASSEMBLY__ */ | ||
189 | |||
190 | /* | ||
191 | * GET_DESC_BASE reads the descriptor base of the specified segment. | ||
192 | * | ||
193 | * Args: | ||
194 | * idx - descriptor index | ||
195 | * gdt - GDT pointer | ||
196 | * base - 32bit register to which the base will be written | ||
197 | * lo_w - lo word of the "base" register | ||
198 | * lo_b - lo byte of the "base" register | ||
199 | * hi_b - hi byte of the low word of the "base" register | ||
200 | * | ||
201 | * Example: | ||
202 | * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) | ||
203 | * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. | ||
204 | */ | ||
205 | #define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ | ||
206 | movb idx*8+4(gdt), lo_b; \ | ||
207 | movb idx*8+7(gdt), hi_b; \ | ||
208 | shll $16, base; \ | ||
209 | movw idx*8+2(gdt), lo_w; | ||
210 | |||
196 | #endif /* !__ASSEMBLY__ */ | 211 | #endif /* !__ASSEMBLY__ */ |
197 | 212 | ||
198 | #endif | 213 | #endif |