ia64/xen-unstable

view xen/arch/x86/x86_64/entry.S @ 3780:f368e743fc2e

bitkeeper revision 1.1159.1.568 (420ba33bo4Ly13qI5cHgZttHha5_-g)

Change do_set_callbacks hypercall for x86/64 to not take any selector
values, but to take a syscall_entry point.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 10 18:08:59 2005 +0000 (2005-02-10)
parents 118e0a3af9b0
children 1d13ed9582e0
line source
1 /*
2 * Hypercall and fault low-level handling routines.
3 *
4 * Copyright (c) 2005, K A Fraser
5 */
7 #include <xen/config.h>
8 #include <xen/errno.h>
9 #include <xen/softirq.h>
10 #include <asm/asm_defns.h>
11 #include <asm/apicdef.h>
12 #include <asm/page.h>
13 #include <public/xen.h>
15 #define GET_CURRENT(reg) \
16 movq $STACK_SIZE-8, reg; \
17 orq %rsp, reg; \
18 andq $~7,reg; \
19 movq (reg),reg;
21 ALIGN
22 restore_all_guest:
23 btr $_TF_failsafe_return,EDOMAIN_thread_flags(%rbx)
24 jc failsafe_callback
25 RESTORE_ALL
26 testw $TRAP_syscall,4(%rsp)
27 jz 1f
28 addq $8,%rsp
29 popq %rcx
30 addq $8,%rsp
31 popq %r11
32 popq %rsp
33 sysretq
34 1: addq $8,%rsp
35 FLT1: iretq
36 .section .fixup,"ax"
37 FIX1: popq -15*8-8(%rsp) # error_code/entry_vector
38 SAVE_ALL # 15*8 bytes pushed
39 movq -8(%rsp),%rsi # error_code/entry_vector
40 sti # after stack abuse (-1024(%rsp))
41 pushq $__HYPERVISOR_DS # SS
42 leaq 8(%rsp),%rax
43 pushq %rax # RSP
44 pushf # RFLAGS
45 pushq $__HYPERVISOR_CS # CS
46 leaq DBLFLT1(%rip),%rax
47 pushq %rax # RIP
48 pushq %rsi # error_code/entry_vector
49 jmp error_code
50 DBLFLT1:GET_CURRENT(%rbx)
51 jmp test_all_events
52 DBLFIX1:GET_CURRENT(%rbx)
53 bts $_TF_failsafe_return,EDOMAIN_thread_flags(%rbx)
54 jc domain_crash # cannot reenter failsafe code
55 jmp test_all_events # will return via failsafe code
56 .previous
57 .section __pre_ex_table,"a"
58 .quad FLT1,FIX1
59 .previous
60 .section __ex_table,"a"
61 .quad DBLFLT1,DBLFIX1
62 .previous
64 /* No special register assumptions */
65 failsafe_callback:
66 GET_CURRENT(%rbx)
67 leaq EDOMAIN_trap_bounce(%rbx),%rdx
68 movq EDOMAIN_failsafe_addr(%rbx),%rax
69 movq %rax,TRAPBOUNCE_eip(%rdx)
70 movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
71 call create_bounce_frame
72 RESTORE_ALL
73 addq $8,%rsp
74 FLT2: iret
75 .section .fixup,"ax"
76 FIX2: pushq %rbx
77 GET_CURRENT(%rbx)
78 orb $TF_failsafe_return,EDOMAIN_thread_flags(%rbx)
79 popq %rbx
80 jmp FIX1
81 .section __pre_ex_table,"a"
82 .quad FLT2,FIX2
83 .previous
85 ALIGN
86 restore_all_xen:
87 RESTORE_ALL
88 addq $8,%rsp
89 iretq
91 /*
92 * %rax = hypercall vector
93 * %rdi, %rsi, %rdx, %r10, %r8, %9 = hypercall arguments
94 * %r11, %rcx = SYSCALL-saved %rflags and %rip
95 * NB. We must move %r10 to %rcx for C function-calling ABI.
96 */
97 ALIGN
98 ENTRY(syscall_enter)
99 movl $__GUEST_SS,8(%rsp)
100 pushq %r11
101 pushq $__GUEST_CS
102 pushq %rcx
103 pushq $0
104 movl $TRAP_syscall,4(%rsp)
105 SAVE_ALL
106 GET_CURRENT(%rbx)
107 testb $TF_kernel_mode,EDOMAIN_thread_flags(%rbx)
108 jnz hypercall
110 leaq EDOMAIN_trap_bounce(%rbx),%rdx
111 movq EDOMAIN_syscall_addr(%rbx),%rax
112 movq %rax,TRAPBOUNCE_eip(%rdx)
113 movw $0,TRAPBOUNCE_flags(%rdx)
114 pushq restore_all_guest(%rip)
115 jmp create_bounce_frame
117 hypercall:
118 sti
119 movq %r10,%rcx
120 andq $(NR_hypercalls-1),%rax
121 leaq SYMBOL_NAME(hypercall_table)(%rip),%r10
122 callq *(%r10,%rax,8)
123 movq %rax,XREGS_rax(%rsp) # save the return value
125 test_all_events:
126 cli # tests must not race interrupts
127 /*test_softirqs:*/
128 movl EDOMAIN_processor(%rbx),%eax
129 shl $6,%rax # sizeof(irq_cpustat) == 64
130 leaq SYMBOL_NAME(irq_stat)(%rip),%rcx
131 testl $~0,(%rcx,%rax,1)
132 jnz process_softirqs
133 /*test_guest_events:*/
134 movq EDOMAIN_vcpu_info(%rbx),%rax
135 testb $0xFF,VCPUINFO_upcall_mask(%rax)
136 jnz restore_all_guest
137 testb $0xFF,VCPUINFO_upcall_pending(%rax)
138 jz restore_all_guest
139 /*process_guest_events:*/
140 leaq EDOMAIN_trap_bounce(%rbx),%rdx
141 movq EDOMAIN_event_addr(%rbx),%rax
142 movq %rax,TRAPBOUNCE_eip(%rdx)
143 movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
144 call create_bounce_frame
145 movq EDOMAIN_vcpu_info(%rbx),%rax
146 movb $1,VCPUINFO_upcall_mask(%rax) # Upcalls masked during delivery
147 jmp restore_all_guest
149 ALIGN
150 process_softirqs:
151 sti
152 call SYMBOL_NAME(do_softirq)
153 jmp test_all_events
155 /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS STACK: */
156 /* { RCX, R11, [DS-GS,] [CR2,] [ERRCODE,] RIP, CS, RFLAGS, RSP, SS } */
157 /* %rdx == trap_bounce, %rbx == task_struct */
158 /* %rax,%rcx are clobbered. %rsi contains new XREGS_rsp. */
159 create_bounce_frame:
160 /* Push new frame at existing %rsp if already in guest-OS mode. */
161 movq XREGS_rsp+8(%rsp),%rsi
162 testb $TF_kernel_mode,EDOMAIN_thread_flags(%rbx)
163 jnz 1f
164 /* Push new frame at registered guest-OS stack base. */
165 movq EDOMAIN_kernel_sp(%rbx),%rsi
166 1: movq $HYPERVISOR_VIRT_START,%rax
167 cmpq %rax,%rsi
168 jb 1f # In +ve address space? Then okay.
169 movq $HYPERVISOR_VIRT_END+60,%rax
170 cmpq %rax,%rsi
171 jb domain_crash # Above Xen private area? Then okay.
172 1: subq $40,%rsi
173 movq XREGS_ss+8(%rsp),%rax
174 FLT3: movq %rax,32(%rsi) # SS
175 movq XREGS_rsp+8(%rsp),%rax
176 FLT4: movq %rax,24(%rsi) # RSP
177 movq XREGS_eflags+8(%rsp),%rax
178 FLT5: movq %rax,16(%rsi) # RFLAGS
179 movq XREGS_cs+8(%rsp),%rax
180 FLT6: movq %rax,8(%rsi) # CS
181 movq XREGS_rip+8(%rsp),%rax
182 FLT7: movq %rax,(%rsi) # RIP
183 movb TRAPBOUNCE_flags(%rdx),%cl
184 testb $TBF_EXCEPTION_ERRCODE,%cl
185 jz 1f
186 subq $8,%rsi
187 movq TRAPBOUNCE_error_code(%rdx),%rax
188 FLT8: movq %rax,(%rsi) # ERROR CODE
189 testb $TBF_EXCEPTION_CR2,%cl
190 jz 2f
191 subq $8,%rsi
192 movq TRAPBOUNCE_cr2(%rdx),%rax
193 FLT9: movq %rax,(%rsi) # CR2
194 1: testb $TBF_FAILSAFE,%cl
195 jz 2f
196 subq $32,%rsi
197 movl %gs,%eax
198 FLT10: movq %rax,24(%rsi) # GS
199 movl %fs,%eax
200 FLT11: movq %rax,16(%rsi) # FS
201 movl %es,%eax
202 FLT12: movq %rax,8(%rsi) # ES
203 movl %ds,%eax
204 FLT13: movq %rax,(%rsi) # DS
205 2: subq $16,%rsi
206 movq XREGS_r11+8(%rsp),%rax
207 FLT14: movq %rax,(%rsi) # R11
208 movq XREGS_rcx+8(%rsp),%rax
209 FLT15: movq %rax,(%rsi) # RCX
210 /* Rewrite our stack frame and return to guest-OS mode. */
211 /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
212 movb $0,TRAPBOUNCE_flags(%rdx)
213 bts $_TF_kernel_mode,EDOMAIN_thread_flags(%rbx)
214 jc 1f
215 swapgs
216 movq %rbx,%rdi
217 call SYMBOL_NAME(write_ptbase)
218 1: movl $TRAP_syscall,XREGS_entry_vector+8(%rsp)
219 andl $0xfffcbeff,XREGS_eflags+8(%rsp)
220 movl $__GUEST_SS,XREGS_ss+8(%rsp)
221 movq %rsi,XREGS_rsp+8(%rsp)
222 movl $__GUEST_CS,XREGS_cs+8(%rsp)
223 movq TRAPBOUNCE_eip(%rdx),%rax
224 movq %rax,XREGS_rip+8(%rsp)
225 ret
226 .section .fixup,"ax"
227 FIX3: sti
228 popq %rsi
229 addq $8,%rsp # Discard create_b_frame return address
230 pushq $__HYPERVISOR_DS # SS
231 leaq 8(%rsp),%rax
232 pushq %rax # RSP
233 pushf # RFLAGS
234 pushq $__HYPERVISOR_CS # CS
235 leaq DBLFLT2(%rip),%rax
236 pushq %rax # RIP
237 pushq %rsi # error_code/entry_vector
238 jmp error_code
239 DBLFLT2:jmp process_guest_exception_and_events
240 .previous
241 .section __pre_ex_table,"a"
242 .quad FLT3,FIX3 , FLT4,FIX3 , FLT5,FIX3 , FLT6,FIX3
243 .quad FLT7,FIX3 , FLT8,FIX3 , FLT9,FIX3 , FLT10,FIX3
244 .quad FLT11,FIX3 , FLT12,FIX3 , FLT13,FIX3 , FLT14,FIX3 , FLT15,FIX3
245 .previous
246 .section __ex_table,"a"
247 .quad DBLFLT2,domain_crash
248 .previous
250 ALIGN
251 process_guest_exception_and_events:
252 leaq EDOMAIN_trap_bounce(%rbx),%rdx
253 testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
254 jz test_all_events
255 cli # create_bounce_frame needs CLI for pre-exceptions to work
256 call create_bounce_frame
257 jmp test_all_events
259 ALIGN
260 ENTRY(ret_from_intr)
261 GET_CURRENT(%rbx)
262 testb $3,XREGS_cs(%rsp)
263 jnz test_all_events
264 jmp restore_all_xen
266 ALIGN
267 error_code:
268 SAVE_ALL
269 testb $X86_EFLAGS_IF>>8,XREGS_eflags+1(%rsp)
270 jz exception_with_ints_disabled
271 1: sti
272 movq %rsp,%rdi
273 movl XREGS_entry_vector(%rsp),%eax
274 leaq SYMBOL_NAME(exception_table)(%rip),%rdx
275 callq *(%rdx,%rax,8)
276 jmp restore_all_xen
278 exception_with_ints_disabled:
279 testb $3,XREGS_cs(%rsp) # interrupts disabled outside Xen?
280 jnz 1b # it really does happen!
281 # (e.g., DOM0 X server)
282 movq XREGS_rip(%rsp),%rdi
283 call search_pre_exception_table
284 testq %rax,%rax # no fixup code for faulting EIP?
285 jz FATAL_exception_with_ints_disabled
286 movq %rax,XREGS_rip(%rsp)
287 movq %rsp,%rsi
288 subq $8,%rsp
289 movq %rsp,%rdi
290 movq $XREGS_kernel_sizeof/8,%rcx
291 rep; movsq # make room for error_code/entry_vector
292 movq XREGS_error_code(%rsp),%rax # error_code/entry_vector
293 movq %rax,XREGS_kernel_sizeof(%rsp)
294 jmp restore_all_xen # return to fixup code
296 FATAL_exception_with_ints_disabled:
297 movl XREGS_entry_vector(%rsp),%edi
298 movq %rsp,%rsi
299 call SYMBOL_NAME(fatal_trap)
300 ud2
302 ENTRY(divide_error)
303 pushq $0
304 movl $TRAP_divide_error,4(%rsp)
305 jmp error_code
307 ENTRY(coprocessor_error)
308 pushq $0
309 movl $TRAP_copro_error,4(%rsp)
310 jmp error_code
312 ENTRY(simd_coprocessor_error)
313 pushq $0
314 movl $TRAP_simd_error,4(%rsp)
315 jmp error_code
317 ENTRY(device_not_available)
318 pushq $0
319 movl $TRAP_no_device,4(%rsp)
320 jmp error_code
322 ENTRY(debug)
323 pushq $0
324 movl $TRAP_debug,4(%rsp)
325 jmp error_code
327 ENTRY(int3)
328 pushq $0
329 movl $TRAP_int3,4(%rsp)
330 jmp error_code
332 ENTRY(overflow)
333 pushq $0
334 movl $TRAP_overflow,4(%rsp)
335 jmp error_code
337 ENTRY(bounds)
338 pushq $0
339 movl $TRAP_bounds,4(%rsp)
340 jmp error_code
342 ENTRY(invalid_op)
343 pushq $0
344 movl $TRAP_invalid_op,4(%rsp)
345 jmp error_code
347 ENTRY(coprocessor_segment_overrun)
348 pushq $0
349 movl $TRAP_copro_seg,4(%rsp)
350 jmp error_code
352 ENTRY(invalid_TSS)
353 movl $TRAP_invalid_tss,4(%rsp)
354 jmp error_code
356 ENTRY(segment_not_present)
357 movl $TRAP_no_segment,4(%rsp)
358 jmp error_code
360 ENTRY(stack_segment)
361 movl $TRAP_stack_error,4(%rsp)
362 jmp error_code
364 ENTRY(general_protection)
365 movl $TRAP_gp_fault,4(%rsp)
366 jmp error_code
368 ENTRY(alignment_check)
369 movl $TRAP_alignment_check,4(%rsp)
370 jmp error_code
372 ENTRY(page_fault)
373 movl $TRAP_page_fault,4(%rsp)
374 jmp error_code
376 ENTRY(machine_check)
377 pushq $0
378 movl $TRAP_machine_check,4(%rsp)
379 jmp error_code
381 ENTRY(spurious_interrupt_bug)
382 pushq $0
383 movl $TRAP_spurious_int,4(%rsp)
384 jmp error_code
386 ENTRY(double_fault)
387 movl $TRAP_double_fault,4(%rsp)
388 jmp error_code
390 ENTRY(nmi)
391 pushq $0
392 SAVE_ALL
393 inb $0x61,%al
394 movl %eax,%esi # reason
395 movq %rsp,%rdi # regs
396 call SYMBOL_NAME(do_nmi)
397 jmp restore_all_xen
399 .data
401 ENTRY(exception_table)
402 .quad SYMBOL_NAME(do_divide_error)
403 .quad SYMBOL_NAME(do_debug)
404 .quad 0 # nmi
405 .quad SYMBOL_NAME(do_int3)
406 .quad SYMBOL_NAME(do_overflow)
407 .quad SYMBOL_NAME(do_bounds)
408 .quad SYMBOL_NAME(do_invalid_op)
409 .quad SYMBOL_NAME(math_state_restore)
410 .quad SYMBOL_NAME(do_double_fault)
411 .quad SYMBOL_NAME(do_coprocessor_segment_overrun)
412 .quad SYMBOL_NAME(do_invalid_TSS)
413 .quad SYMBOL_NAME(do_segment_not_present)
414 .quad SYMBOL_NAME(do_stack_segment)
415 .quad SYMBOL_NAME(do_general_protection)
416 .quad SYMBOL_NAME(do_page_fault)
417 .quad SYMBOL_NAME(do_spurious_interrupt_bug)
418 .quad SYMBOL_NAME(do_coprocessor_error)
419 .quad SYMBOL_NAME(do_alignment_check)
420 .quad SYMBOL_NAME(do_machine_check)
421 .quad SYMBOL_NAME(do_simd_coprocessor_error)
423 ENTRY(hypercall_table)
424 .quad SYMBOL_NAME(do_set_trap_table) /* 0 */
425 .quad SYMBOL_NAME(do_mmu_update)
426 .quad SYMBOL_NAME(do_set_gdt)
427 .quad SYMBOL_NAME(do_stack_switch)
428 .quad SYMBOL_NAME(do_set_callbacks)
429 .quad SYMBOL_NAME(do_fpu_taskswitch) /* 5 */
430 .quad SYMBOL_NAME(do_sched_op)
431 .quad SYMBOL_NAME(do_dom0_op)
432 .quad SYMBOL_NAME(do_set_debugreg)
433 .quad SYMBOL_NAME(do_get_debugreg)
434 .quad SYMBOL_NAME(do_update_descriptor) /* 10 */
435 .quad SYMBOL_NAME(do_ni_hypercall)
436 .quad SYMBOL_NAME(do_dom_mem_op)
437 .quad SYMBOL_NAME(do_multicall)
438 .quad SYMBOL_NAME(do_update_va_mapping)
439 .quad SYMBOL_NAME(do_set_timer_op) /* 15 */
440 .quad SYMBOL_NAME(do_event_channel_op)
441 .quad SYMBOL_NAME(do_xen_version)
442 .quad SYMBOL_NAME(do_console_io)
443 .quad SYMBOL_NAME(do_physdev_op)
444 .quad SYMBOL_NAME(do_grant_table_op) /* 20 */
445 .quad SYMBOL_NAME(do_vm_assist)
446 .quad SYMBOL_NAME(do_update_va_mapping_otherdomain)
447 .quad SYMBOL_NAME(do_switch_to_user)
448 .quad SYMBOL_NAME(do_boot_vcpu)
449 .quad SYMBOL_NAME(do_set_segment_base) /* 25 */
450 .rept NR_hypercalls-((.-hypercall_table)/4)
451 .quad SYMBOL_NAME(do_ni_hypercall)
452 .endr