2 * trap.S: Trap and world switch handlers
4 * Leendert van Doorn, leendert@watson.ibm.com
5 * Copyright (c) 2005, International Business Machines Corporation.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place - Suite 330, Boston, MA 02111-1307 USA.
25 * All processor exception/faults/interrupts end up here.
27 * On an exception/fault, the processor pushes CS:EIP, SS, ESP and an
28 * optional error code onto the stack. The common_trap routine
29 * below saves the processor context and transfers control to trap()
30 * whose job it is to virtualize and pass on the trap.
32 .macro TRAP_HANDLER trapno error
36 pushl $0 /* dummy error code */
50 TRAP_HANDLER 0, 0 /* divide error */
51 TRAP_HANDLER 1, 0 /* debug */
52 TRAP_HANDLER 2, 0 /* NMI interrupt */
53 TRAP_HANDLER 3, 0 /* breakpoint */
54 TRAP_HANDLER 4, 0 /* overflow */
55 TRAP_HANDLER 5, 0 /* BOUND range exceeded */
56 TRAP_HANDLER 6, 0 /* invalid opcode */
57 TRAP_HANDLER 7, 0 /* device not available */
58 TRAP_HANDLER 8, 1 /* double fault */
59 TRAP_HANDLER 9, 0 /* coprocessor segment overrun */
60 TRAP_HANDLER 10, 1 /* invalid TSS */
61 TRAP_HANDLER 11, 1 /* segment not present */
62 TRAP_HANDLER 12, 1 /* stack-segment fault */
63 TRAP_HANDLER 13, 1 /* general protection */
64 TRAP_HANDLER 14, 1 /* page fault */
65 TRAP_HANDLER 15, 0 /* reserved */
66 TRAP_HANDLER 16, 0 /* FPU floating-point error */
67 TRAP_HANDLER 17, 1 /* alignment check */
68 TRAP_HANDLER 18, 0 /* machine check */
69 TRAP_HANDLER 19, 0 /* SIMD floating-point error */
70 TRAP_HANDLER 20, 0 /* reserved */
71 TRAP_HANDLER 21, 0 /* reserved */
72 TRAP_HANDLER 22, 0 /* reserved */
73 TRAP_HANDLER 23, 0 /* reserved */
74 TRAP_HANDLER 24, 0 /* reserved */
75 TRAP_HANDLER 25, 0 /* reserved */
76 TRAP_HANDLER 26, 0 /* reserved */
77 TRAP_HANDLER 27, 0 /* reserved */
78 TRAP_HANDLER 28, 0 /* reserved */
79 TRAP_HANDLER 29, 0 /* reserved */
80 TRAP_HANDLER 30, 0 /* reserved */
81 TRAP_HANDLER 31, 0 /* reserved */
82 TRAP_HANDLER 32, 0 /* irq 0 */
83 TRAP_HANDLER 33, 0 /* irq 1 */
84 TRAP_HANDLER 34, 0 /* irq 2 */
85 TRAP_HANDLER 35, 0 /* irq 3 */
86 TRAP_HANDLER 36, 0 /* irq 4 */
87 TRAP_HANDLER 37, 0 /* irq 5 */
88 TRAP_HANDLER 38, 0 /* irq 6 */
89 TRAP_HANDLER 39, 0 /* irq 7 */
90 TRAP_HANDLER 40, 0 /* irq 8 */
91 TRAP_HANDLER 41, 0 /* irq 9 */
92 TRAP_HANDLER 42, 0 /* irq 10 */
93 TRAP_HANDLER 43, 0 /* irq 11 */
94 TRAP_HANDLER 44, 0 /* irq 12 */
95 TRAP_HANDLER 45, 0 /* irq 13 */
96 TRAP_HANDLER 46, 0 /* irq 14 */
97 TRAP_HANDLER 47, 0 /* irq 15 */
102 common_trap: /* common trap handler */
109 movl $DATA_SELECTOR, %eax /* make sure these are sane */
119 call trap /* trap(trapno, errno, regs) */
128 addl $8, %esp /* skip trapno, errno */
134 * A world switch to real mode occured. The hypervisor saved the
135 * executing context into "oldctx" and instantiated "newctx", which
136 * gets us here. Here we push a stack frame that is compatible with
137 * a trap frame (see above) so that we can handle this event as a
142 .globl switch_to_real_mode
144 pushl oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
145 pushl oldctx+VMX_ASSIST_CTX_FS_SEL
146 pushl oldctx+VMX_ASSIST_CTX_DS_SEL
147 pushl oldctx+VMX_ASSIST_CTX_ES_SEL
148 pushl oldctx+VMX_ASSIST_CTX_SS_SEL
149 pushl oldctx+VMX_ASSIST_CTX_ESP
150 pushl oldctx+VMX_ASSIST_CTX_EFLAGS
151 pushl oldctx+VMX_ASSIST_CTX_CS_SEL
152 pushl oldctx+VMX_ASSIST_CTX_EIP
153 pushl $-1 /* trapno, errno */
171 * Switch to protected mode. At this point all the registers have
172 * been reloaded by trap_return and all we have to do is cause a
173 * world switch by turning on CR0.PE.
177 .globl switch_to_protected_mode
178 switch_to_protected_mode:
179 movl oldctx+VMX_ASSIST_CTX_CR0, %esp
180 movl %esp, %cr0 /* actual world switch ! */
190 .asciz "World switch to protected mode failed\n"