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