📄 entry.s
字号:
/* * Compatibility hypercall routines. */#include <xen/config.h>#include <xen/errno.h>#include <xen/softirq.h>#include <asm/asm_defns.h>#include <asm/apicdef.h>#include <asm/page.h>#include <asm/desc.h>#include <public/xen.h>#define GET_GUEST_REGS(reg) \ movq $~(STACK_SIZE-1),reg; \ andq %rsp,reg; \ orq $(STACK_SIZE-CPUINFO_sizeof),reg;#define GET_CURRENT(reg) \ movq $STACK_SIZE-8, reg; \ orq %rsp, reg; \ andq $~7,reg; \ movq (reg),reg; ALIGNENTRY(compat_hypercall) pushq $0 movl $TRAP_syscall,4(%rsp) SAVE_ALL GET_CURRENT(%rbx) cmpl $NR_hypercalls,%eax jae compat_bad_hypercall#ifndef NDEBUG /* Deliberately corrupt parameter regs not used by this hypercall. */ pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi pushq UREGS_rbp+5*8(%rsp) leaq compat_hypercall_args_table(%rip),%r10 movq $6,%rcx subb (%r10,%rax,1),%cl movq %rsp,%rdi movl $0xDEADBEEF,%eax rep stosq popq %r8 ; popq %r9 ; xchgl %r8d,%r9d /* Args 5&6: zero extend */ popq %rdx; popq %rcx; xchgl %edx,%ecx /* Args 3&4: zero extend */ popq %rdi; popq %rsi; xchgl %edi,%esi /* Args 1&2: zero extend */ movl UREGS_rax(%rsp),%eax pushq %rax pushq UREGS_rip+8(%rsp)#define SHADOW_BYTES 16 /* Shadow EIP + shadow hypercall # */#else /* Relocate argument registers and zero-extend to 64 bits. */ movl %eax,%eax /* Hypercall # */ xchgl %ecx,%esi /* Arg 2, Arg 4 */ movl %edx,%edx /* Arg 3 */ movl %edi,%r8d /* Arg 5 */ movl %ebp,%r9d /* Arg 6 */ movl UREGS_rbx(%rsp),%edi /* Arg 1 */#define SHADOW_BYTES 0 /* No on-stack shadow state */#endif cmpb $0,tb_init_done(%rip) je 1f call trace_hypercall /* Now restore all the registers that trace_hypercall clobbered */ movl UREGS_rax+SHADOW_BYTES(%rsp),%eax /* Hypercall # */ movl UREGS_rbx+SHADOW_BYTES(%rsp),%edi /* Arg 1 */ movl UREGS_rcx+SHADOW_BYTES(%rsp),%esi /* Arg 2 */ movl UREGS_rdx+SHADOW_BYTES(%rsp),%edx /* Arg 3 */ movl UREGS_rsi+SHADOW_BYTES(%rsp),%ecx /* Arg 4 */ movl UREGS_rdi+SHADOW_BYTES(%rsp),%r8d /* Arg 5 */ movl UREGS_rbp+SHADOW_BYTES(%rsp),%r9d /* Arg 6 */#undef SHADOW_BYTES1: leaq compat_hypercall_table(%rip),%r10 PERFC_INCR(PERFC_hypercalls, %rax, %rbx) callq *(%r10,%rax,8)#ifndef NDEBUG /* Deliberately corrupt parameter regs used by this hypercall. */ popq %r10 # Shadow RIP cmpq %r10,UREGS_rip+8(%rsp) popq %rcx # Shadow hypercall index jne compat_skip_clobber /* If RIP has changed then don't clobber. */ leaq compat_hypercall_args_table(%rip),%r10 movb (%r10,%rcx,1),%cl movl $0xDEADBEEF,%r10d testb %cl,%cl; jz compat_skip_clobber; movl %r10d,UREGS_rbx(%rsp) cmpb $2, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rcx(%rsp) cmpb $3, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdx(%rsp) cmpb $4, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rsi(%rsp) cmpb $5, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdi(%rsp) cmpb $6, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rbp(%rsp)compat_skip_clobber:#endif movl %eax,UREGS_rax(%rsp) # save the return value/* %rbx: struct vcpu */ENTRY(compat_test_all_events) cli # tests must not race interrupts/*compat_test_softirqs:*/ movl VCPU_processor(%rbx),%eax shlq $IRQSTAT_shift,%rax leaq irq_stat(%rip),%rcx testl $~0,(%rcx,%rax,1) jnz compat_process_softirqs testb $1,VCPU_mce_pending(%rbx) jnz compat_process_mce testb $1,VCPU_nmi_pending(%rbx) jnz compat_process_nmicompat_test_guest_events: movq VCPU_vcpu_info(%rbx),%rax testb $0xFF,COMPAT_VCPUINFO_upcall_mask(%rax) jnz compat_restore_all_guest testb $0xFF,COMPAT_VCPUINFO_upcall_pending(%rax) jz compat_restore_all_guest/*compat_process_guest_events:*/ sti leaq VCPU_trap_bounce(%rbx),%rdx movl VCPU_event_addr(%rbx),%eax movl %eax,TRAPBOUNCE_eip(%rdx) movl VCPU_event_sel(%rbx),%eax movw %ax,TRAPBOUNCE_cs(%rdx) movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) call compat_create_bounce_frame jmp compat_test_all_events ALIGN/* %rbx: struct vcpu */compat_process_softirqs: sti call do_softirq jmp compat_test_all_events ALIGN/* %rbx: struct vcpu */compat_process_mce: cmpw $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx) jae compat_test_guest_events sti movb $0,VCPU_mce_pending(%rbx) call set_guest_machinecheck_trapbounce testl %eax,%eax jz compat_test_all_events movw VCPU_trap_priority(%rbx),%dx # safe priority for the movw %dx,VCPU_old_trap_priority(%rbx) # iret hypercall movw $VCPU_TRAP_MCE,VCPU_trap_priority(%rbx) jmp compat_process_trap ALIGN/* %rbx: struct vcpu */compat_process_nmi: cmpw $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx) jae compat_test_guest_events sti movb $0,VCPU_nmi_pending(%rbx) call set_guest_nmi_trapbounce testl %eax,%eax jz compat_test_all_events movw VCPU_trap_priority(%rbx),%dx # safe priority for the movw %dx,VCPU_old_trap_priority(%rbx) # iret hypercall movw $VCPU_TRAP_NMI,VCPU_trap_priority(%rbx) /* FALLTHROUGH */compat_process_trap: leaq VCPU_trap_bounce(%rbx),%rdx call compat_create_bounce_frame jmp compat_test_all_eventscompat_bad_hypercall: movl $-ENOSYS,UREGS_rax(%rsp) jmp compat_test_all_events/* %rbx: struct vcpu, interrupts disabled */compat_restore_all_guest: ASSERT_INTERRUPTS_DISABLED RESTORE_ALL addq $8,%rsp.Lft0: iretq.section .fixup,"ax".Lfx0: sti SAVE_ALL movq UREGS_error_code(%rsp),%rsi movq %rsp,%rax andq $~0xf,%rsp pushq $__HYPERVISOR_DS # SS pushq %rax # RSP pushfq # RFLAGS pushq $__HYPERVISOR_CS # CS leaq .Ldf0(%rip),%rax pushq %rax # RIP pushq %rsi # error_code/entry_vector jmp handle_exception.Ldf0: GET_CURRENT(%rbx) jmp compat_test_all_eventscompat_failsafe_callback: GET_CURRENT(%rbx) leaq VCPU_trap_bounce(%rbx),%rdx movl VCPU_failsafe_addr(%rbx),%eax movl %eax,TRAPBOUNCE_eip(%rdx) movl VCPU_failsafe_sel(%rbx),%eax movw %ax,TRAPBOUNCE_cs(%rdx) movb $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) jnc 1f orb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)1: call compat_create_bounce_frame jmp compat_test_all_events.previous.section __pre_ex_table,"a" .quad .Lft0,.Lfx0.previous.section __ex_table,"a" .quad .Ldf0,compat_failsafe_callback.previous/* %rdx: trap_bounce, %rbx: struct vcpu */ENTRY(compat_post_handle_exception) testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) jz compat_test_all_events call compat_create_bounce_frame movb $0,TRAPBOUNCE_flags(%rdx) jmp compat_test_all_eventsENTRY(compat_syscall) cmpb $0,VCPU_syscall32_disables_events(%rbx) movzwl VCPU_syscall32_sel(%rbx),%esi movq VCPU_syscall32_addr(%rbx),%rax setne %cl leaq VCPU_trap_bounce(%rbx),%rdx testl $~3,%esi leal (,%rcx,TBF_INTERRUPT),%ecx jz 2f1: movq %rax,TRAPBOUNCE_eip(%rdx) movw %si,TRAPBOUNCE_cs(%rdx)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -