Xen Test Framework
entry_32.S
Go to the documentation of this file.
1#include <arch/idt.h>
2#include <arch/page.h>
3#include <arch/processor.h>
4#include <arch/segment.h>
5#include <xtf/asm_macros.h>
6
7/*
8
9Stack frame layout:
10
11| Xen | Hardware | Notes |
12|-------------------+-------------------+----------------------|
13| <r> | <r> | <l> |
14|-------------------+-------------------+----------------------|
15| %ss | %ss | only on stack switch |
16| %esp | %esp | only on stack switch |
17| eflags | eflags | |
18| upcall_mask / %cs | %cs | |
19| %eip | %eip | |
20| %esp-> error_code | %esp-> error_code | if applicable |
21
22These stubs push an error_code of zero (if applicable) to make a common layout
23for the frame. A further word of metadata is then pushed, currently just
24containing the entry vector.
25
26*/
27
28.macro env_IRET /* Environment specific version of `iret`. */
29#if defined(CONFIG_PV)
30
31 jmp HYPERCALL_iret /* PV guests use the 'iret' hypercall. */
32
33#else
34 iretl /* HVM guests use a real 'iret' instruction. */
35#endif
36.endm
37
38.macro exception_entry sym vec
39
40ENTRY(entry_\sym)
41
42 .if !((1 << \vec) & X86_EXC_HAVE_EC)
43 /* Push dummy error code (if needed) to align stack. */
44 push $0
45 .endif
46
47 /* Push metadata (entry vector). */
48 push $\vec
49
50 jmp handle_exception
51
52ENDFUNC(entry_\sym)
53.endm
54
55exception_entry DE X86_EXC_DE
56exception_entry DB X86_EXC_DB
57exception_entry NMI X86_EXC_NMI
58exception_entry BP X86_EXC_BP
59exception_entry OF X86_EXC_OF
60exception_entry BR X86_EXC_BR
61exception_entry UD X86_EXC_UD
62exception_entry NM X86_EXC_NM
63exception_entry DF X86_EXC_DF
64exception_entry TS X86_EXC_TS
65exception_entry NP X86_EXC_NP
66exception_entry SS X86_EXC_SS
67exception_entry GP X86_EXC_GP
68exception_entry PF X86_EXC_PF
69exception_entry MF X86_EXC_MF
70exception_entry AC X86_EXC_AC
71exception_entry MC X86_EXC_MC
72exception_entry XM X86_EXC_XM
73exception_entry VE X86_EXC_VE
74
75 .align 16
76handle_exception:
77
78 push %es
79 push %ds
80
81 SAVE_ALL
82
83 mov $__KERN_DS, %eax /* Restore data segments. */
84 mov %eax, %ds
85 mov %eax, %es
86
87 mov %esp, %eax /* struct cpu_regs * */
88 call do_exception
89
90 RESTORE_ALL
91
92 pop %ds
93 pop %es
94
95 add $8, %esp /* Pop error_code/entry_vector. */
96
97 env_IRET
98ENDFUNC(handle_exception)
99
100
101ENTRY(entry_ret_to_kernel) /* int $X86_VEC_RET2KERN */
102 mov %ebp, %esp /* Restore %esp to exec_user_param()'s context. */
103 ret
104ENDFUNC(entry_ret_to_kernel)
105
106ENTRY(exec_user_param) /* %eax = ulong (*fn)(ulong p1), %edx = ulong p1 */
107 push %ebp
108
109 /* Prepare to "call" exec_user_stub(). */
110 push $1f /* Fake return addr as if we'd called exec_user_stub(). */
111 mov %esp, %ebp /* Stash %esp for entry_ret_to_kernel(). */
112
113 /* Prepare an IRET frame. */
114 push exec_user_ss /* SS */
115 /* ESP */
116 push $user_stack + PAGE_SIZE
117 pushf /* EFLAGS */
118
119 /* Apply and/or masks to eflags. */
120 mov exec_user_efl_and_mask, %ecx
121 and %ecx, (%esp)
122 mov exec_user_efl_or_mask, %ecx
123 or %ecx, (%esp)
124
125 push exec_user_cs /* CS */
126 push $exec_user_stub /* EIP */
127
128 env_IRET /* Drop to user privilege. */
129
1301: /* entry_ret_to_kernel() returns here with a sensible stack. */
131 pop %ebp
132 ret
133
134ENDFUNC(exec_user_param)
135
136.pushsection .text.user, "ax", @progbits
137ENTRY(exec_user_stub) /* %eax = ulong (*fn)(ulong p1), %edx = ulong p1 */
138 xchg %eax, %edx /* Swap p1 to be first parameter to fn(). */
139 call *%edx /* fn(p1) */
140
141 int $X86_VEC_RET2KERN /* Return to kernel privilege. */
142ENDFUNC(exec_user_stub)
143.popsection
144
145ENTRY(entry_EVTCHN)
146 push $0
147 push $0x200
148
149 push %es
150 push %ds
151
152 SAVE_ALL
153
154 mov $__KERN_DS, %eax /* Restore data segments. */
155 mov %eax, %ds
156 mov %eax, %es
157
158 mov %esp, %eax /* struct cpu_regs * */
159 call do_evtchn
160
161 RESTORE_ALL
162
163 pop %ds
164 pop %es
165
166 add $8, %esp /* Pop error_code/entry_vector. */
167
168 env_IRET
169ENDFUNC(entry_EVTCHN)
170
171#if defined(CONFIG_PV)
172ENTRY(entry_SYSCALL)
173 push $0
174 push $0x100
175
176 push %es
177 push %ds
178
179 SAVE_ALL
180
181 mov $__KERN_DS, %eax /* Restore data segments. */
182 mov %eax, %ds
183 mov %eax, %es
184
185 mov %esp, %eax /* struct cpu_regs * */
186 call do_syscall
187
188 RESTORE_ALL
189
190 pop %ds
191 pop %es
192
193 add $8, %esp /* Pop error_code/entry_vector. */
194
195 jmp HYPERCALL_iret
196ENDFUNC(entry_SYSCALL)
197
198ENTRY(entry_SYSENTER)
199 push $0
200 push $0x200
201
202 push %es
203 push %ds
204
205 SAVE_ALL
206
207 mov $__KERN_DS, %eax /* Restore data segments. */
208 mov %eax, %ds
209 mov %eax, %es
210
211 mov %esp, %eax /* struct cpu_regs * */
212 call do_sysenter
213
214 RESTORE_ALL
215
216 pop %ds
217 pop %es
218
219 add $8, %esp /* Pop error_code/entry_vector. */
220
221 jmp HYPERCALL_iret
222ENDFUNC(entry_SYSENTER)
223#endif
224
225/*
226 * Local variables:
227 * tab-width: 8
228 * indent-tabs-mode: nil
229 * End:
230 */