github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/vmx/vmcs_hierarchy.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 "vmm_dbg.h"
    17  #include "memory_allocator.h"
    18  #include "vmm_objects.h"
    19  #include "vmcs_api.h"
    20  #include "vmcs_sw_object.h"
    21  #include "vmcs_actual.h"
    22  #include "vmcs_hierarchy.h"
    23  #include "file_codes.h"
    24  #define VMM_DEADLOOP()          VMM_DEADLOOP_LOG(VMCS_HIERARCHY_C)
    25  #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(VMCS_HIERARCHY_C, __condition)
    26  #ifdef JLMDEBUG
    27  #include "jlmdebug.h"
    28  #endif
    29  
    30  typedef struct {
    31      VMCS_OBJECT    *vmcs;
    32      LIST_ELEMENT    list[1];
    33  } VMCS_1_DESCRIPTOR;
    34  VMCS_1_DESCRIPTOR *vmcs_hierarchy_vmcs1_lkup(VMCS_HIERARCHY *obj, VMCS_OBJECT *vmcs);
    35  
    36  
    37  VMM_STATUS vmcs_hierarchy_create(VMCS_HIERARCHY *obj, GUEST_CPU_HANDLE gcpu)
    38  {
    39      VMM_STATUS status;
    40  
    41  #ifdef JLMDEBUG
    42      bprint("vmcs_hierarchy_create\n");
    43  #endif
    44      VMM_ASSERT(obj);
    45      VMCS_OBJECT * v= vmcs_act_create(gcpu);
    46      if(NULL==v) {
    47  #ifdef JLMDEBUG
    48          bprint("vmcs_act_creat retuns NULL\n");
    49          LOOP_FOREVER
    50  #endif
    51      }
    52      obj->vmcs[VMCS_MERGED] = v;
    53      obj->vmcs[VMCS_LEVEL_0] = v;
    54      if (NULL == obj->vmcs[VMCS_LEVEL_0]) {
    55          VMM_LOG(mask_anonymous, level_trace,"Failed to create merged VMCS\n");
    56  #ifdef JLMDEBUG
    57          bprint("failed to create merged VMCS\n");
    58          LOOP_FOREVER
    59  #endif
    60          status = VMM_ERROR;
    61      }
    62      else {
    63          obj->vmcs[VMCS_LEVEL_1] = NULL;
    64          list_init(obj->vmcs_1_list);
    65          status = VMM_OK;
    66      }
    67      return status;
    68  }
    69  
    70  #ifdef INCLUDE_UNUSED_CODE
    71  VMM_STATUS vmcs_hierarchy_add_vmcs( VMCS_HIERARCHY * obj, GUEST_CPU_HANDLE gcpu, ADDRESS gpa)
    72  {
    73      VMM_STATUS status = VMM_ERROR;
    74      VMCS_1_DESCRIPTOR *desc;
    75  
    76      VMM_ASSERT(obj);
    77      VMM_ASSERT(obj->vmcs[VMCS_MERGED]);
    78      do { 
    79          desc = vmm_malloc(sizeof(*desc));
    80          if (NULL == desc) {
    81              VMM_LOG(mask_anonymous, level_trace,"Failed to create VMCS-1\n");
    82              break;
    83          }
    84          desc->vmcs = vmcs_1_create(gcpu, gpa);
    85          if (NULL == desc->vmcs) {
    86              VMM_LOG(mask_anonymous, level_trace,"Failed to create VMCS-1\n");
    87              vmm_mfree(desc);
    88              break;
    89          }
    90          // create VMCS-0 if required
    91          if (list_is_empty(obj->vmcs_1_list)) {
    92              obj->vmcs[VMCS_LEVEL_0] = vmcs_0_create(obj->vmcs[VMCS_MERGED]);
    93              if (NULL == obj->vmcs[VMCS_LEVEL_0]) {
    94                  VMM_LOG(mask_anonymous, level_trace,"Failed to create VMCS-0\n");
    95                  vmcs_destroy(desc->vmcs);
    96                  vmm_mfree(desc);
    97                  break;
    98              }
    99          }
   100          // here all objects were successfully created
   101          // we can add new VMCS-1 to the list
   102          list_add(obj->vmcs_1_list, desc->list);
   103          // newly created VMCS-1 becomes the current
   104          obj->vmcs[VMCS_LEVEL_1] = desc->vmcs;
   105          status = VMM_OK;
   106      } while (0);
   107      return status;
   108  }
   109  
   110  VMM_STATUS vmcs_hierarchy_remove_vmcs(VMCS_HIERARCHY *obj, VMCS_OBJECT *vmcs_1)
   111  {
   112      VMM_STATUS status = VMM_ERROR;
   113      VMM_ASSERT(obj);
   114  
   115      do {
   116          VMCS_1_DESCRIPTOR   *desc;
   117  
   118          desc = vmcs_hierarchy_vmcs1_lkup(obj, vmcs_1);
   119          if (NULL == desc) {
   120              VMM_LOG(mask_anonymous, level_trace,"Cannot remove VMCS-1 %P. Not found\n");
   121              break;
   122          }
   123          // we found proper VMCS-1. Remove it.
   124          status = VMM_OK;
   125          list_remove(desc->list);
   126          vmcs_destroy(desc->vmcs);
   127          vmm_mfree(desc);
   128          // if there is no level-1 vmcs, then remove vmcs-0 also
   129          if (list_is_empty(obj->vmcs_1_list)) {
   130              vmcs_destroy(obj->vmcs[VMCS_LEVEL_0]);
   131              obj->vmcs[VMCS_LEVEL_0] = obj->vmcs[VMCS_MERGED];
   132          }
   133          else {
   134              // select current VMCS-1
   135              desc = LIST_NEXT(obj->vmcs_1_list,VMCS_1_DESCRIPTOR, list);
   136              obj->vmcs[VMCS_LEVEL_1] = desc->vmcs;
   137          }
   138      } while (0);
   139      return status;
   140  }
   141  #endif
   142  
   143  
   144  VMCS_OBJECT* vmcs_hierarchy_get_vmcs(VMCS_HIERARCHY *obj, VMCS_LEVEL level)
   145  {
   146      VMCS_OBJECT *vmcs= NULL;
   147  
   148  #ifdef JLMDEBUG1
   149      bprint("vmcs_hierarchy_get_vmcs %p %d, ", obj, level);
   150      if(level>4)
   151          return NULL;
   152  #endif
   153      VMM_ASSERT(obj);
   154      if (((int)level)>=VMCS_LEVEL_0 && ((int)level)<VMCS_LEVELS) {
   155          vmcs = obj->vmcs[level];
   156      }
   157      else {
   158          VMM_LOG(mask_anonymous, level_trace,"Invalid VMCS level\n");
   159          VMM_ASSERT(0);
   160  #ifdef JLMDEBUG1
   161          bprint("vmcs_hierarchy_get_vmcs returning NULL\n");
   162          LOOP_FOREVER
   163  #endif
   164          vmcs = NULL;
   165      }
   166  #ifdef JLMDEBUG1
   167      bprint(" returning %p\n", vmcs);
   168  #endif
   169      return vmcs;
   170  }
   171  
   172  #ifdef INCLUDE_UNUSED_CODE
   173  VMCS_OBJECT * vmcs_hierarchy_get_next_vmcs_1(VMCS_HIERARCHY *obj)
   174  {
   175      VMM_ASSERT(obj);
   176  
   177      if (NULL != obj->vmcs[VMCS_LEVEL_1]) {
   178          VMCS_1_DESCRIPTOR *desc = vmcs_hierarchy_vmcs1_lkup(obj, obj->vmcs[VMCS_LEVEL_1]);
   179          VMM_ASSERT(desc);
   180  
   181          desc = LIST_NEXT(desc->list, VMCS_1_DESCRIPTOR, list);
   182          obj->vmcs[VMCS_LEVEL_1] = desc->vmcs;
   183      }
   184      return  obj->vmcs[VMCS_LEVEL_1];
   185  }
   186  
   187  VMCS_OBJECT * vmcs_hierarchy_select_vmcs_1(VMCS_HIERARCHY *obj, VMCS_OBJECT *vmcs)
   188  {
   189      VMCS_1_DESCRIPTOR   *desc;
   190  
   191      VMM_ASSERT(obj);
   192      desc = vmcs_hierarchy_vmcs1_lkup(obj, vmcs);
   193      if (NULL != desc) {
   194          // found
   195          obj->vmcs[VMCS_LEVEL_1] = desc->vmcs;
   196      }
   197      else {
   198          VMM_LOG(mask_anonymous, level_trace,"Failed to select VMCS-1. Should be added first.\n");
   199          VMM_ASSERT(0);
   200      }
   201      return obj->vmcs[VMCS_LEVEL_1];
   202  }
   203  
   204  VMCS_1_DESCRIPTOR *vmcs_hierarchy_vmcs1_lkup(VMCS_HIERARCHY *obj, VMCS_OBJECT *vmcs)
   205  {
   206      LIST_ELEMENT      *iter;
   207      VMCS_1_DESCRIPTOR *desc;    // output
   208  
   209      VMM_ASSERT(obj);
   210      LIST_FOR_EACH(obj->vmcs_1_list, iter) {
   211          desc = LIST_ENTRY(iter, VMCS_1_DESCRIPTOR, list);
   212          if (vmcs == desc->vmcs) {
   213              // math
   214              return desc;
   215          }
   216      }
   217      return NULL;    // not found
   218  }
   219  #endif
   220