diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2006-09-26 04:52:35 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:35 -0400 |
commit | 522e93e3fcdbf00ba85c72fde6df28cfc0486a65 (patch) | |
tree | c6d1d0fd3109a667ca4ee0c0f8dc8a2fe4767240 /arch/i386/kernel/traps.c | |
parent | 02ba1a32dbd3d406530a17a2643a8f0f8cbf3acc (diff) |
[PATCH] i386: Descriptor and trap table cleanups.
The implementation comes from Zach's [RFC, PATCH 10/24] i386 Vmi
descriptor changes:
Descriptor and trap table cleanups. Add cleanly written accessors for
IDT and GDT gates so the subarch may override them. Note that this
allows the hypervisor to transparently tweak the DPL of the descriptors
as well as the RPL of segments in those descriptors, with no unnecessary
kernel code modification. It also allows the hypervisor implementation
of the VMI to tweak the gates, allowing for custom exception frames or
extra layers of indirection above the guest fault / IRQ handlers.
Signed-off-by: Zachary Amsden <zach@vmware.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 24 |
1 files changed, 5 insertions, 19 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index bdf949c30c7c..00d643f3de41 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -1165,20 +1165,6 @@ void __init trap_init_f00f_bug(void) | |||
1165 | } | 1165 | } |
1166 | #endif | 1166 | #endif |
1167 | 1167 | ||
1168 | #define _set_gate(gate_addr,type,dpl,addr,seg) \ | ||
1169 | do { \ | ||
1170 | int __d0, __d1; \ | ||
1171 | __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ | ||
1172 | "movw %4,%%dx\n\t" \ | ||
1173 | "movl %%eax,%0\n\t" \ | ||
1174 | "movl %%edx,%1" \ | ||
1175 | :"=m" (*((long *) (gate_addr))), \ | ||
1176 | "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ | ||
1177 | :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ | ||
1178 | "3" ((char *) (addr)),"2" ((seg) << 16)); \ | ||
1179 | } while (0) | ||
1180 | |||
1181 | |||
1182 | /* | 1168 | /* |
1183 | * This needs to use 'idt_table' rather than 'idt', and | 1169 | * This needs to use 'idt_table' rather than 'idt', and |
1184 | * thus use the _nonmapped_ version of the IDT, as the | 1170 | * thus use the _nonmapped_ version of the IDT, as the |
@@ -1187,7 +1173,7 @@ do { \ | |||
1187 | */ | 1173 | */ |
1188 | void set_intr_gate(unsigned int n, void *addr) | 1174 | void set_intr_gate(unsigned int n, void *addr) |
1189 | { | 1175 | { |
1190 | _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); | 1176 | _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS); |
1191 | } | 1177 | } |
1192 | 1178 | ||
1193 | /* | 1179 | /* |
@@ -1195,22 +1181,22 @@ void set_intr_gate(unsigned int n, void *addr) | |||
1195 | */ | 1181 | */ |
1196 | static inline void set_system_intr_gate(unsigned int n, void *addr) | 1182 | static inline void set_system_intr_gate(unsigned int n, void *addr) |
1197 | { | 1183 | { |
1198 | _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); | 1184 | _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS); |
1199 | } | 1185 | } |
1200 | 1186 | ||
1201 | static void __init set_trap_gate(unsigned int n, void *addr) | 1187 | static void __init set_trap_gate(unsigned int n, void *addr) |
1202 | { | 1188 | { |
1203 | _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); | 1189 | _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); |
1204 | } | 1190 | } |
1205 | 1191 | ||
1206 | static void __init set_system_gate(unsigned int n, void *addr) | 1192 | static void __init set_system_gate(unsigned int n, void *addr) |
1207 | { | 1193 | { |
1208 | _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); | 1194 | _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS); |
1209 | } | 1195 | } |
1210 | 1196 | ||
1211 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) | 1197 | static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) |
1212 | { | 1198 | { |
1213 | _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); | 1199 | _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3)); |
1214 | } | 1200 | } |
1215 | 1201 | ||
1216 | 1202 | ||