aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2006-09-26 04:52:35 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:35 -0400
commit522e93e3fcdbf00ba85c72fde6df28cfc0486a65 (patch)
treec6d1d0fd3109a667ca4ee0c0f8dc8a2fe4767240 /arch/i386
parent02ba1a32dbd3d406530a17a2643a8f0f8cbf3acc (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')
-rw-r--r--arch/i386/kernel/traps.c24
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) \
1169do { \
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 */
1188void set_intr_gate(unsigned int n, void *addr) 1174void 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 */
1196static inline void set_system_intr_gate(unsigned int n, void *addr) 1182static 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
1201static void __init set_trap_gate(unsigned int n, void *addr) 1187static 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
1206static void __init set_system_gate(unsigned int n, void *addr) 1192static 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
1211static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) 1197static 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