ia64/xen-unstable

view extras/mini-os/traps.c @ 8988:49c02a7a92dd

Remove TBF_SLOW_IRET hack from x86/64 Xen return-to-guest
path. Guest should set up flags for itself in its own
NMI handler.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Feb 23 18:30:43 2006 +0100 (2006-02-23)
parents 06d84bf87159
children c176d2e45117
line source
2 #include <os.h>
3 #include <traps.h>
4 #include <hypervisor.h>
5 #include <mm.h>
6 #include <lib.h>
8 /*
9 * These are assembler stubs in entry.S.
10 * They are the actual entry points for virtual exceptions.
11 */
12 void divide_error(void);
13 void debug(void);
14 void int3(void);
15 void overflow(void);
16 void bounds(void);
17 void invalid_op(void);
18 void device_not_available(void);
19 void coprocessor_segment_overrun(void);
20 void invalid_TSS(void);
21 void segment_not_present(void);
22 void stack_segment(void);
23 void general_protection(void);
24 void page_fault(void);
25 void coprocessor_error(void);
26 void simd_coprocessor_error(void);
27 void alignment_check(void);
28 void spurious_interrupt_bug(void);
29 void machine_check(void);
32 extern void do_exit(void);
34 void dump_regs(struct pt_regs *regs)
35 {
36 printk("FIXME: proper register dump (with the stack dump)\n");
37 }
40 static void do_trap(int trapnr, char *str, struct pt_regs * regs, unsigned long error_code)
41 {
42 printk("FATAL: Unhandled Trap %d (%s), error code=0x%lx\n", trapnr, str, error_code);
43 printk("Regs address %p\n", regs);
44 dump_regs(regs);
45 do_exit();
46 }
48 #define DO_ERROR(trapnr, str, name) \
49 void do_##name(struct pt_regs * regs, unsigned long error_code) \
50 { \
51 do_trap(trapnr, str, regs, error_code); \
52 }
54 #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
55 void do_##name(struct pt_regs * regs, unsigned long error_code) \
56 { \
57 do_trap(trapnr, str, regs, error_code); \
58 }
60 DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
61 DO_ERROR( 3, "int3", int3)
62 DO_ERROR( 4, "overflow", overflow)
63 DO_ERROR( 5, "bounds", bounds)
64 DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
65 DO_ERROR( 7, "device not available", device_not_available)
66 DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
67 DO_ERROR(10, "invalid TSS", invalid_TSS)
68 DO_ERROR(11, "segment not present", segment_not_present)
69 DO_ERROR(12, "stack segment", stack_segment)
70 DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
71 DO_ERROR(18, "machine check", machine_check)
73 void do_page_fault(struct pt_regs *regs, unsigned long error_code,
74 unsigned long addr)
75 {
76 printk("Page fault at linear address %p\n", addr);
77 dump_regs(regs);
78 #ifdef __x86_64__
79 /* FIXME: _PAGE_PSE */
80 {
81 unsigned long *tab = (unsigned long *)start_info.pt_base;
82 unsigned long page;
84 printk("Pagetable walk from %p:\n", tab);
86 page = tab[l4_table_offset(addr)];
87 tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
88 printk(" L4 = %p (%p)\n", page, tab);
90 page = tab[l3_table_offset(addr)];
91 tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
92 printk(" L3 = %p (%p)\n", page, tab);
94 page = tab[l2_table_offset(addr)];
95 tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
96 printk(" L2 = %p (%p)\n", page, tab);
98 page = tab[l1_table_offset(addr)];
99 printk(" L1 = %p\n", page);
100 }
101 #endif
102 do_exit();
103 }
105 void do_general_protection(struct pt_regs *regs, long error_code)
106 {
107 printk("GPF %p, error_code=%lx\n", regs, error_code);
108 dump_regs(regs);
109 do_exit();
110 }
113 void do_debug(struct pt_regs * regs)
114 {
115 printk("Debug exception\n");
116 #define TF_MASK 0x100
117 regs->eflags &= ~TF_MASK;
118 dump_regs(regs);
119 do_exit();
120 }
122 void do_coprocessor_error(struct pt_regs * regs)
123 {
124 printk("Copro error\n");
125 dump_regs(regs);
126 do_exit();
127 }
129 void simd_math_error(void *eip)
130 {
131 printk("SIMD error\n");
132 }
134 void do_simd_coprocessor_error(struct pt_regs * regs)
135 {
136 printk("SIMD copro error\n");
137 }
139 void do_spurious_interrupt_bug(struct pt_regs * regs)
140 {
141 }
143 /*
144 * Submit a virtual IDT to teh hypervisor. This consists of tuples
145 * (interrupt vector, privilege ring, CS:EIP of handler).
146 * The 'privilege ring' field specifies the least-privileged ring that
147 * can trap to that vector using a software-interrupt instruction (INT).
148 */
149 static trap_info_t trap_table[] = {
150 { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
151 { 1, 0, __KERNEL_CS, (unsigned long)debug },
152 { 3, 3, __KERNEL_CS, (unsigned long)int3 },
153 { 4, 3, __KERNEL_CS, (unsigned long)overflow },
154 { 5, 3, __KERNEL_CS, (unsigned long)bounds },
155 { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
156 { 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
157 { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
158 { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
159 { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
160 { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
161 { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
162 { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
163 { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
164 { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
165 { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
166 { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
167 { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
168 { 0, 0, 0, 0 }
169 };
173 void trap_init(void)
174 {
175 HYPERVISOR_set_trap_table(trap_table);
176 }