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