diff options
Diffstat (limited to 'include/asm-x86/desc.h')
-rw-r--r-- | include/asm-x86/desc.h | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 268a012bcd79..a44c4dc70590 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h | |||
@@ -29,11 +29,17 @@ static inline void fill_ldt(struct desc_struct *desc, | |||
29 | extern struct desc_ptr idt_descr; | 29 | extern struct desc_ptr idt_descr; |
30 | extern gate_desc idt_table[]; | 30 | extern gate_desc idt_table[]; |
31 | 31 | ||
32 | struct gdt_page { | ||
33 | struct desc_struct gdt[GDT_ENTRIES]; | ||
34 | } __attribute__((aligned(PAGE_SIZE))); | ||
35 | DECLARE_PER_CPU(struct gdt_page, gdt_page); | ||
36 | |||
37 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | ||
38 | { | ||
39 | return per_cpu(gdt_page, cpu).gdt; | ||
40 | } | ||
41 | |||
32 | #ifdef CONFIG_X86_64 | 42 | #ifdef CONFIG_X86_64 |
33 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | ||
34 | extern struct desc_ptr cpu_gdt_descr[]; | ||
35 | /* the cpu gdt accessor */ | ||
36 | #define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) | ||
37 | 43 | ||
38 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, | 44 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, |
39 | unsigned dpl, unsigned ist, unsigned seg) | 45 | unsigned dpl, unsigned ist, unsigned seg) |
@@ -51,16 +57,6 @@ static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, | |||
51 | } | 57 | } |
52 | 58 | ||
53 | #else | 59 | #else |
54 | struct gdt_page { | ||
55 | struct desc_struct gdt[GDT_ENTRIES]; | ||
56 | } __attribute__((aligned(PAGE_SIZE))); | ||
57 | DECLARE_PER_CPU(struct gdt_page, gdt_page); | ||
58 | |||
59 | static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | ||
60 | { | ||
61 | return per_cpu(gdt_page, cpu).gdt; | ||
62 | } | ||
63 | |||
64 | static inline void pack_gate(gate_desc *gate, unsigned char type, | 60 | static inline void pack_gate(gate_desc *gate, unsigned char type, |
65 | unsigned long base, unsigned dpl, unsigned flags, | 61 | unsigned long base, unsigned dpl, unsigned flags, |
66 | unsigned short seg) | 62 | unsigned short seg) |
@@ -192,8 +188,8 @@ static inline void native_set_ldt(const void *addr, unsigned int entries) | |||
192 | unsigned cpu = smp_processor_id(); | 188 | unsigned cpu = smp_processor_id(); |
193 | ldt_desc ldt; | 189 | ldt_desc ldt; |
194 | 190 | ||
195 | set_tssldt_descriptor(&ldt, (unsigned long)addr, | 191 | set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT, |
196 | DESC_LDT, entries * sizeof(ldt) - 1); | 192 | entries * LDT_ENTRY_SIZE - 1); |
197 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, | 193 | write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, |
198 | &ldt, DESC_LDT); | 194 | &ldt, DESC_LDT); |
199 | asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); | 195 | asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); |
@@ -311,6 +307,28 @@ static inline void set_intr_gate(unsigned int n, void *addr) | |||
311 | _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); | 307 | _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); |
312 | } | 308 | } |
313 | 309 | ||
310 | #define SYS_VECTOR_FREE 0 | ||
311 | #define SYS_VECTOR_ALLOCED 1 | ||
312 | |||
313 | extern int first_system_vector; | ||
314 | extern char system_vectors[]; | ||
315 | |||
316 | static inline void alloc_system_vector(int vector) | ||
317 | { | ||
318 | if (system_vectors[vector] == SYS_VECTOR_FREE) { | ||
319 | system_vectors[vector] = SYS_VECTOR_ALLOCED; | ||
320 | if (first_system_vector > vector) | ||
321 | first_system_vector = vector; | ||
322 | } else | ||
323 | BUG(); | ||
324 | } | ||
325 | |||
326 | static inline void alloc_intr_gate(unsigned int n, void *addr) | ||
327 | { | ||
328 | alloc_system_vector(n); | ||
329 | set_intr_gate(n, addr); | ||
330 | } | ||
331 | |||
314 | /* | 332 | /* |
315 | * This routine sets up an interrupt gate at directory privilege level 3. | 333 | * This routine sets up an interrupt gate at directory privilege level 3. |
316 | */ | 334 | */ |