github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/host/hw/em64t/em64t_vmx.s (about) 1 # 2 # Copyright (c) 2013 Intel Corporation 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # Unless required by applicable law or agreed to in writing, software 9 # distributed under the License is distributed on an "AS IS" BASIS, 10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # See the License for the specific language governing permissions and 12 # limitations under the License. 13 # 14 15 # Reset the stack after a C-function call. 16 # %rcx must be set to the number of arguments before this macro is called. 17 .macro RESTORE_C_STACK 18 cmp $4, %rcx 19 ja 1f 20 mov $4, %rcx # at least 4 arguments 21 1: # parameters are normalized 22 shl $3, %rcx 23 add %rcx, %rsp 24 .endm 25 26 27 # Prepare the stack for a call to a C function. 28 # %rcx must be set to the number of arguments before this macro is called. 29 .macro ALLOCATE_C_STACK 30 cmp $4, %rcx 31 ja 1f 32 mov $4, %rcx 33 1: 34 shl $3, %rcx 35 sub %rcx, %rsp 36 .endm 37 38 # vmexit_func is called when a vmexit happens. 39 .globl vmexit_func 40 .type vmexit_func, @function 41 vmexit_func: 42 call gcpu_save_registers 43 xor %rcx, %rcx 44 ALLOCATE_C_STACK 45 46 call vmexit_common_handler 47 jmp . # should never return 48 49 50 # vmentry_func is called by eVMM to perform a vmlaunch/vmresume. 51 # %rdi (the first argument) is set to 1 if this is the first time this 52 # function is called, and it's set to 0 otherwise. 53 .globl vmentry_func 54 .type vmentry_func, @function 55 vmentry_func: 56 push %rdi 57 cmp $0, %rdi 58 jnz 1f 59 call gcpu_restore_registers 60 vmresume # Resume execution of Guest Virtual Machine 61 62 jmp 2f 63 1: 64 # remove the following 65 #call fixupvmcs # temporary debug function 66 call gcpu_restore_registers 67 vmlaunch # Launch execution of Guest Virtual Machine 68 69 2: 70 pushfq # use RFLAGS as argument if VMRESUME failed 71 pop %rdx # save RFLAGS in RDX 72 mov $1, %rcx # RCX contains number of argments for vmentry_failure_function 73 ALLOCATE_C_STACK # for for vmentry_failure_function 74 mov %rdx, %rdi # 1st argument (passed via RDI) contains RFLAGS 75 call vmentry_failure_function 76 mov $1, %rcx # RCX contains number of argments for vmentry_failure_function 77 RESTORE_C_STACK 78 pop %rdi # restore RDI. stack is expected to be the same as in entry point 79 jmp vmentry_func # retry 80 81 82 # hw_vmcall converts a C function call in the guest into a vmcall VM exit 83 # with arguments that match the vmcall calling convention for eVMM. That is: 84 # vmcall_id in RCX 85 # arg1 in RDX 86 # arg2 in RDI 87 # arg3 in RSI 88 # 89 # Note that the original code could avoid dealing with the first two arguments, 90 # since they are also the first two arguments in the Microsoft calling 91 # convention. But these arguments need to be transformed by this version. 92 # In this case, the arguments come in as rdi, rsi, rcx, rdx, and they need to be 93 # rcx, rdx, rdi, rsi. So, we swap rdi and rcx, and we swap rsi and rdx. 94 .globl hw_vmcall 95 .type hw_vmcall, @function 96 hw_vmcall: 97 push %rdi 98 mov %rcx, %rdi 99 pop %rcx 100 101 push %rsi 102 mov %rdx, %rsi 103 pop %rdx 104 105 mov $0x024694D40, %rax 106 vmcall 107 ret