github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/vmx/vmx.c (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  #include "vmm_defs.h"
    16  #include "hw_utils.h"
    17  #include "hw_vmx_utils.h"
    18  #ifdef JLMDEBUG
    19  #include "jlmdebug.h"
    20  #endif
    21  
    22  
    23  int vmx_on(UINT64* ptr_to_vmcs_region) {
    24      int  ret= 0;
    25      UINT64   address= *ptr_to_vmcs_region;
    26  #ifdef JLMDEBUG
    27      bprint("vmx_on %p %llx\n", ptr_to_vmcs_region, address);
    28  #endif
    29      __asm__ volatile(
    30          "\tmovl $0, %[ret]\n"
    31          "\tvmxon %[address]\n"
    32          "\tjnc    1f\n"
    33          "\tmovl  $2, %[ret]\n"
    34          "\tjmp    2f\n"
    35      "1:\n"
    36          "\tjnz   2f\n"
    37          "\tmovl  $1, %[ret]\n"
    38      "2:\n"
    39      : [ret]"=g" (ret)
    40      :[address]"m" (address)
    41      :);
    42      return ret;
    43  }
    44  
    45  void vmx_off() {
    46  #ifdef JLMDEBUG
    47      bprint("vmx_off\n");
    48  #endif
    49      __asm__ volatile(
    50          "\tvmxoff\n"
    51      :: :"cc");
    52      return;
    53  }
    54  
    55  
    56  int vmx_vmclear(UINT64* ptr_to_vmcs_region) {
    57      int      ret= 0;
    58      UINT64   address= *ptr_to_vmcs_region;
    59  #ifdef JLMDEBUG1
    60      bprint("vmclear %p %llx\n", ptr_to_vmcs_region, address);
    61  #endif
    62      __asm__ volatile(
    63          "\tmovl $0, %[ret]\n"
    64          "\tvmclear %[address]\n"
    65          "\tjnc    1f\n"
    66          "\tmovl  $2, %[ret]\n"
    67          "\tjmp    2f\n"
    68      "1:\n"
    69          "\tjnz   2f\n"
    70          "\tmovl  $1, %[ret]\n"
    71      "2:\n"
    72      : [ret]"=g" (ret)
    73      : [address]"m"(address)
    74      :"memory");
    75      return ret;
    76  }
    77  
    78  int hw_vmx_flush_current_vmcs(UINT64 *address) {
    79      return vmx_vmclear(address);
    80  }
    81  
    82  int vmx_vmlaunch() {
    83      int ret= 0;
    84  #ifdef JLMDEBUG
    85      bprint("vmxlaunch\n");
    86  #endif
    87      __asm__ volatile(
    88          "\tmovl $0, %[ret]\n"
    89          "\tvmlaunch\n"
    90          "\tjnc    1f\n"
    91          "\tmovl  $2, %[ret]\n"
    92          "\tjmp    2f\n"
    93      "1:\n"
    94          "\tjnz   2f\n"
    95          "\tmovl  $1, %[ret]\n"
    96      "2:\n"
    97      :  [ret]"=g" (ret)
    98      :: "memory");
    99      return ret;
   100  }
   101  
   102  int vmx_vmresume() {
   103      int ret= 0;
   104  #ifdef JLMDEBUG
   105      bprint("vmresume\n");
   106  #endif
   107      __asm__ volatile(
   108          "\tmovl $0, %[ret]\n"
   109          "\tvmresume\n"
   110          "\tjnc    1f\n"
   111          "\tmovl  $2, %[ret]\n"
   112          "\tjmp    2f\n"
   113      "1:\n"
   114          "\tjnz   2f\n"
   115          "\tmovl  $1, %[ret]\n"
   116      "2:\n"
   117      : [ret]"=g" (ret)
   118      ::"cc", "memory");
   119      return ret;
   120  }
   121  
   122  
   123  int vmx_vmptrld(UINT64 *ptr_to_vmcs_region) {
   124      int      ret= 0;
   125      UINT64   address= *ptr_to_vmcs_region;
   126  #ifdef JLMDEBUG1
   127      bprint("vmptrld %p %llx\n", ptr_to_vmcs_region, address);
   128  #endif
   129      __asm__ volatile(
   130          "\tmovl $0, %[ret]\n"
   131          "\tvmptrld %[address]\n"
   132          "\tjnc    1f\n"
   133          "\tmovl  $2, %[ret]\n"
   134          "\tjmp    2f\n"
   135      "1:\n"
   136          "\tjnz   2f\n"
   137          "\tmovl  $1, %[ret]\n"
   138      "2:\n"
   139      : [ret]"=g" (ret)
   140      :[address] "m" (address)
   141      :"memory");
   142      return ret;
   143  }
   144  
   145  void vmx_vmptrst(UINT64 *ptr_to_vmcs_region) {
   146      UINT64   address= *ptr_to_vmcs_region;
   147  #ifdef JLMDEBUG1
   148      bprint("vmptrst %p %llx\n", ptr_to_vmcs_region, address);
   149  #endif
   150      __asm__ volatile(
   151          "\tvmptrst %[address]\n"
   152      ::[address] "m" (address)
   153      :"memory");
   154      return;
   155  }
   156  
   157  
   158  int vmx_vmread(UINT64 index, UINT64 *value) {
   159      int ret= 0;
   160  #ifdef JLMDEBUG1
   161      bprint("vmread, waiting %d, 0x%016lx\n", index, *value);
   162  #endif
   163      __asm__ volatile(
   164          "\tmovq %[index], %%rax\n"
   165          "\tmovl $0, %[ret]\n"
   166          "\tvmread %%rax, %%rax\n"
   167          "\tjnc   1f\n"
   168          "\tmovl  $2, %[ret]\n"
   169          "\tjmp   3f\n"
   170      "1:\n"
   171          "\tjnz   2f\n"
   172          "\tmovl  $1, %[ret]\n"
   173          "\tjmp   3f\n"
   174      "2:\n"
   175          "\tmovq %[value], %%rbx\n"
   176          "\tmovq %%rax, (%%rbx)\n"
   177      "3:\n"
   178      : [ret]"=g" (ret)
   179      : [value] "p"(value), [index] "g"(index)
   180      :"%rax", "%rbx");
   181  #ifdef JLMDEBUG1
   182      bprint("vmread, done 0x%016lx\n", *value);
   183  #endif
   184      return ret;
   185  }
   186  
   187  
   188  int vmx_vmwrite(UINT64 index, UINT64 value) {
   189      int ret= 0;
   190  #ifdef JLMDEBUG1
   191      bprint("vmwrite, %p\n", value);
   192  #endif
   193      __asm__ volatile(
   194          "\tmovq %[index], %%rax\n"
   195          "\tmovq %[value], %%rbx\n"
   196          "\tmovl $0, %[ret]\n"
   197          // "\tvmwrite %%rax, %%rbx\n"
   198          "\tvmwrite %%rbx, %%rax\n"
   199          "\tjnc    1f\n"
   200          "\tmovl  $2, %[ret]\n"
   201          "\tjmp    2f\n"
   202      "1:\n"
   203          "\tjnz   2f\n"
   204          "\tmovl  $1, %[ret]\n"
   205      "2:\n"
   206      : [ret] "=g" (ret) 
   207      : [index] "g"(index), [value] "g"(value)
   208      :"%rbx", "%rax");
   209  #ifdef JLMDEBUG
   210      if(ret!=0)
   211      bprint("vmwrite failed\n");
   212  #endif
   213      return ret;
   214  }
   215  
   216  
   217  int hw_vmx_write_current_vmcs(UINT64 field_id, UINT64 value) {
   218          return vmx_vmwrite(field_id, value);
   219  }
   220  
   221  
   222  int hw_vmx_read_current_vmcs(UINT64 field_id, UINT64 *value) {
   223          return vmx_vmread(field_id, value);
   224  }
   225