diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2008-01-30 07:31:14 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:14 -0500 |
commit | 507f90c9f92592e7630b1c1e87bf92d2c9858cc6 (patch) | |
tree | 23e011c11bc221e1c51702ca7dc748d2b241005d /include/asm-x86/desc.h | |
parent | 54cd0eac7286b83ef1a657d2dddd74e0556209e7 (diff) |
x86: move _set_gate and its users to a common location
This patch moves _set_gate and its users to desc.h. We can now
use common code for x86_64 and i386.
[ mingo@elte.hu: set_system_gate() fixes for nasty crashes. ]
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/asm-x86/desc.h')
-rw-r--r-- | include/asm-x86/desc.h | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index e61a5a38caba..d75bc0634313 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h | |||
@@ -33,6 +33,22 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | |||
33 | extern struct desc_ptr cpu_gdt_descr[]; | 33 | extern struct desc_ptr cpu_gdt_descr[]; |
34 | /* the cpu gdt accessor */ | 34 | /* the cpu gdt accessor */ |
35 | #define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) | 35 | #define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address) |
36 | |||
37 | static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, | ||
38 | unsigned dpl, unsigned ist, unsigned seg) | ||
39 | { | ||
40 | gate->offset_low = PTR_LOW(func); | ||
41 | gate->segment = __KERNEL_CS; | ||
42 | gate->ist = ist; | ||
43 | gate->p = 1; | ||
44 | gate->dpl = dpl; | ||
45 | gate->zero0 = 0; | ||
46 | gate->zero1 = 0; | ||
47 | gate->type = type; | ||
48 | gate->offset_middle = PTR_MIDDLE(func); | ||
49 | gate->offset_high = PTR_HIGH(func); | ||
50 | } | ||
51 | |||
36 | #else | 52 | #else |
37 | struct gdt_page { | 53 | struct gdt_page { |
38 | struct desc_struct gdt[GDT_ENTRIES]; | 54 | struct desc_struct gdt[GDT_ENTRIES]; |
@@ -43,6 +59,16 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) | |||
43 | { | 59 | { |
44 | return per_cpu(gdt_page, cpu).gdt; | 60 | return per_cpu(gdt_page, cpu).gdt; |
45 | } | 61 | } |
62 | |||
63 | static inline void pack_gate(gate_desc *gate, unsigned char type, | ||
64 | unsigned long base, unsigned dpl, unsigned flags, unsigned short seg) | ||
65 | |||
66 | { | ||
67 | gate->a = (seg << 16) | (base & 0xffff); | ||
68 | gate->b = (base & 0xffff0000) | | ||
69 | (((0x80 | type | (dpl << 5)) & 0xff) << 8); | ||
70 | } | ||
71 | |||
46 | #endif | 72 | #endif |
47 | 73 | ||
48 | #ifdef CONFIG_PARAVIRT | 74 | #ifdef CONFIG_PARAVIRT |
@@ -242,6 +268,72 @@ static inline unsigned long get_desc_base(struct desc_struct *desc) | |||
242 | { | 268 | { |
243 | return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); | 269 | return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); |
244 | } | 270 | } |
271 | static inline void _set_gate(int gate, unsigned type, void *addr, | ||
272 | unsigned dpl, unsigned ist, unsigned seg) | ||
273 | { | ||
274 | gate_desc s; | ||
275 | pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); | ||
276 | /* | ||
277 | * does not need to be atomic because it is only done once at | ||
278 | * setup time | ||
279 | */ | ||
280 | write_idt_entry(idt_table, gate, &s); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * This needs to use 'idt_table' rather than 'idt', and | ||
285 | * thus use the _nonmapped_ version of the IDT, as the | ||
286 | * Pentium F0 0F bugfix can have resulted in the mapped | ||
287 | * IDT being write-protected. | ||
288 | */ | ||
289 | static inline void set_intr_gate(unsigned int n, void *addr) | ||
290 | { | ||
291 | BUG_ON((unsigned)n > 0xFF); | ||
292 | _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * This routine sets up an interrupt gate at directory privilege level 3. | ||
297 | */ | ||
298 | static inline void set_system_intr_gate(unsigned int n, void *addr) | ||
299 | { | ||
300 | BUG_ON((unsigned)n > 0xFF); | ||
301 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); | ||
302 | } | ||
303 | |||
304 | static inline void set_trap_gate(unsigned int n, void *addr) | ||
305 | { | ||
306 | BUG_ON((unsigned)n > 0xFF); | ||
307 | _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); | ||
308 | } | ||
309 | |||
310 | static inline void set_system_gate(unsigned int n, void *addr) | ||
311 | { | ||
312 | BUG_ON((unsigned)n > 0xFF); | ||
313 | #ifdef CONFIG_X86_32 | ||
314 | _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); | ||
315 | #else | ||
316 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); | ||
317 | #endif | ||
318 | } | ||
319 | |||
320 | static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) | ||
321 | { | ||
322 | BUG_ON((unsigned)n > 0xFF); | ||
323 | _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); | ||
324 | } | ||
325 | |||
326 | static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) | ||
327 | { | ||
328 | BUG_ON((unsigned)n > 0xFF); | ||
329 | _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); | ||
330 | } | ||
331 | |||
332 | static inline void set_system_gate_ist(int n, void *addr, unsigned ist) | ||
333 | { | ||
334 | BUG_ON((unsigned)n > 0xFF); | ||
335 | _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); | ||
336 | } | ||
245 | 337 | ||
246 | #else | 338 | #else |
247 | /* | 339 | /* |