github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/include/vmcs_api.h (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 #ifndef _VMCS_API_H_ 16 #define _VMCS_API_H_ 17 18 #include "vmm_dbg.h" 19 #include "vmm_objects.h" 20 #include "memory_allocator.h" 21 22 #define VMCS_INVALID_ADDRESS (ADDRESS)(-1) // means that the address is invalid 23 24 25 // VMCS fields 26 typedef enum _VMCS_FIELD { 27 VMCS_VPID = 0, 28 VMCS_EPTP_INDEX, 29 VMCS_CONTROL_VECTOR_PIN_EVENTS, 30 VMCS_CONTROL_VECTOR_PROCESSOR_EVENTS, // Special case - NmiWindow cannot be updated 31 // using this value. Use special APIs to update 32 // NmiWindow setting 33 VMCS_CONTROL2_VECTOR_PROCESSOR_EVENTS, 34 VMCS_EXCEPTION_BITMAP, 35 VMCS_CR3_TARGET_COUNT, 36 VMCS_CR0_MASK, 37 VMCS_CR4_MASK, 38 VMCS_CR0_READ_SHADOW, 39 VMCS_CR4_READ_SHADOW, 40 VMCS_PAGE_FAULT_ERROR_CODE_MASK, 41 VMCS_PAGE_FAULT_ERROR_CODE_MATCH, 42 VMCS_EXIT_CONTROL_VECTOR, 43 VMCS_EXIT_MSR_STORE_COUNT, 44 VMCS_EXIT_MSR_LOAD_COUNT, 45 VMCS_ENTER_CONTROL_VECTOR, 46 VMCS_ENTER_INTERRUPT_INFO, 47 VMCS_ENTER_EXCEPTION_ERROR_CODE, 48 VMCS_ENTER_INSTRUCTION_LENGTH, 49 VMCS_ENTER_MSR_LOAD_COUNT, 50 VMCS_IO_BITMAP_ADDRESS_A, 51 VMCS_IO_BITMAP_ADDRESS_B, 52 VMCS_MSR_BITMAP_ADDRESS, 53 VMCS_EXIT_MSR_STORE_ADDRESS, 54 VMCS_EXIT_MSR_LOAD_ADDRESS, 55 VMCS_ENTER_MSR_LOAD_ADDRESS, 56 VMCS_OSV_CONTROLLING_VMCS_ADDRESS, 57 VMCS_TSC_OFFSET, 58 VMCS_EXIT_INFO_GUEST_PHYSICAL_ADDRESS, 59 VMCS_EXIT_INFO_INSTRUCTION_ERROR_CODE, 60 VMCS_EXIT_INFO_REASON, 61 VMCS_EXIT_INFO_EXCEPTION_INFO, 62 VMCS_EXIT_INFO_EXCEPTION_ERROR_CODE, 63 VMCS_EXIT_INFO_IDT_VECTORING, 64 VMCS_EXIT_INFO_IDT_VECTORING_ERROR_CODE, 65 VMCS_EXIT_INFO_INSTRUCTION_LENGTH, 66 VMCS_EXIT_INFO_INSTRUCTION_INFO, 67 VMCS_EXIT_INFO_QUALIFICATION, 68 VMCS_EXIT_INFO_IO_RCX, 69 VMCS_EXIT_INFO_IO_RSI, 70 VMCS_EXIT_INFO_IO_RDI, 71 VMCS_EXIT_INFO_IO_RIP, 72 VMCS_EXIT_INFO_GUEST_LINEAR_ADDRESS, 73 VMCS_VIRTUAL_APIC_ADDRESS, 74 VMCS_APIC_ACCESS_ADDRESS, 75 VMCS_EXIT_TPR_THRESHOLD, 76 VMCS_EPTP_ADDRESS, 77 VMCS_PREEMPTION_TIMER, 78 VMCS_GUEST_CR0, 79 VMCS_GUEST_CR3, 80 VMCS_GUEST_CR4, 81 VMCS_GUEST_DR7, 82 VMCS_GUEST_ES_SELECTOR, 83 VMCS_GUEST_ES_BASE, 84 VMCS_GUEST_ES_LIMIT, 85 VMCS_GUEST_ES_AR, 86 VMCS_GUEST_CS_SELECTOR, 87 VMCS_GUEST_CS_BASE, 88 VMCS_GUEST_CS_LIMIT, 89 VMCS_GUEST_CS_AR, 90 VMCS_GUEST_SS_SELECTOR, 91 VMCS_GUEST_SS_BASE, 92 VMCS_GUEST_SS_LIMIT, 93 VMCS_GUEST_SS_AR, 94 VMCS_GUEST_DS_SELECTOR, 95 VMCS_GUEST_DS_BASE, 96 VMCS_GUEST_DS_LIMIT, 97 VMCS_GUEST_DS_AR, 98 VMCS_GUEST_FS_SELECTOR, 99 VMCS_GUEST_FS_BASE, 100 VMCS_GUEST_FS_LIMIT, 101 VMCS_GUEST_FS_AR, 102 VMCS_GUEST_GS_SELECTOR, 103 VMCS_GUEST_GS_BASE, 104 VMCS_GUEST_GS_LIMIT, 105 VMCS_GUEST_GS_AR, 106 VMCS_GUEST_LDTR_SELECTOR, 107 VMCS_GUEST_LDTR_BASE, 108 VMCS_GUEST_LDTR_LIMIT, 109 VMCS_GUEST_LDTR_AR, 110 VMCS_GUEST_TR_SELECTOR, 111 VMCS_GUEST_TR_BASE, 112 VMCS_GUEST_TR_LIMIT, 113 VMCS_GUEST_TR_AR, 114 VMCS_GUEST_GDTR_BASE, 115 VMCS_GUEST_GDTR_LIMIT, 116 VMCS_GUEST_IDTR_BASE, 117 VMCS_GUEST_IDTR_LIMIT, 118 VMCS_GUEST_RSP, 119 VMCS_GUEST_RIP, 120 VMCS_GUEST_RFLAGS, 121 VMCS_GUEST_PEND_DBE, 122 VMCS_GUEST_WORKING_VMCS_PTR, 123 VMCS_GUEST_DEBUG_CONTROL, 124 VMCS_GUEST_INTERRUPTIBILITY, 125 VMCS_GUEST_SLEEP_STATE, 126 VMCS_GUEST_SMBASE, 127 VMCS_GUEST_SYSENTER_CS, 128 VMCS_GUEST_SYSENTER_ESP, 129 VMCS_GUEST_SYSENTER_EIP, 130 VMCS_GUEST_PAT, 131 VMCS_GUEST_EFER, 132 VMCS_GUEST_IA32_PERF_GLOBAL_CTRL, 133 VMCS_GUEST_PDPTR0, 134 VMCS_GUEST_PDPTR1, 135 VMCS_GUEST_PDPTR2, 136 VMCS_GUEST_PDPTR3, 137 VMCS_HOST_CR0, 138 VMCS_HOST_CR3, 139 VMCS_HOST_CR4, 140 VMCS_HOST_ES_SELECTOR, 141 VMCS_HOST_CS_SELECTOR, 142 VMCS_HOST_SS_SELECTOR, 143 VMCS_HOST_DS_SELECTOR, 144 VMCS_HOST_FS_SELECTOR, 145 VMCS_HOST_FS_BASE, 146 VMCS_HOST_GS_SELECTOR, 147 VMCS_HOST_GS_BASE, 148 VMCS_HOST_TR_SELECTOR, 149 VMCS_HOST_TR_BASE, 150 VMCS_HOST_GDTR_BASE, 151 VMCS_HOST_IDTR_BASE, 152 VMCS_HOST_RSP, 153 VMCS_HOST_RIP, 154 VMCS_HOST_SYSENTER_CS, 155 VMCS_HOST_SYSENTER_ESP, 156 VMCS_HOST_SYSENTER_EIP, 157 VMCS_HOST_PAT, 158 VMCS_HOST_EFER, 159 VMCS_HOST_IA32_PERF_GLOBAL_CTRL, 160 VMCS_CR3_TARGET_VALUE_0, 161 VMCS_CR3_TARGET_VALUE_1, 162 VMCS_CR3_TARGET_VALUE_2, 163 VMCS_CR3_TARGET_VALUE_3, 164 #ifdef FAST_VIEW_SWITCH 165 VMCS_VMFUNC_CONTROL, 166 VMCS_VMFUNC_EPTP_LIST_ADDRESS, 167 #endif 168 VMCS_VE_INFO_ADDRESS, 169 170 // last 171 VMCS_FIELD_COUNT 172 } VMCS_FIELD; 173 174 #define VMCS_CR3_TARGET_VALUE(__x) (VMCS_CR3_TARGET_VALUE_0 + (__x)) 175 176 177 #define VMCS_NOT_EXISTS 0 178 #define VMCS_READABLE 1 179 #define VMCS_WRITABLE 2 180 #define VMCS_WRITABLE_IN_CACHE 4 181 182 #define VMCS_SIGNATURE 0x12345678 183 184 typedef enum { 185 VMCS_LEVEL_0, // VMCS of current level-1 VMM 186 VMCS_LEVEL_1, // VMCS of level-0 VMM. NULL means no layering 187 VMCS_MERGED, // merged VMCS; when no layering, identical to vmcs0 188 VMCS_LEVELS 189 } VMCS_LEVEL; 190 191 192 struct _VMCS_OBJECT { 193 UINT32 signature; 194 UINT32 level; 195 BOOLEAN skip_access_checking; 196 UINT32 max_num_of_vmexit_store_msrs; 197 UINT32 max_num_of_vmexit_load_msrs; 198 UINT32 max_num_of_vmenter_load_msrs; 199 UINT64 (*vmcs_read)(const struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id); 200 void (*vmcs_write)(struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id, UINT64 value); 201 void (*vmcs_flush_to_cpu)(const struct _VMCS_OBJECT *vmcs); 202 void (*vmcs_flush_to_memory)(struct _VMCS_OBJECT *vmcs); 203 BOOLEAN (*vmcs_is_dirty)(const struct _VMCS_OBJECT *vmcs); 204 GUEST_CPU_HANDLE (*vmcs_get_owner)(const struct _VMCS_OBJECT *vmcs); 205 void (*vmcs_destroy)(struct _VMCS_OBJECT *vmcs); 206 void (*vmcs_add_msr_to_vmexit_store_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value); 207 void (*vmcs_add_msr_to_vmexit_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value); 208 void (*vmcs_add_msr_to_vmenter_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value); 209 void (*vmcs_add_msr_to_vmexit_store_and_vmenter_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value); 210 void (*vmcs_delete_msr_from_vmexit_store_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index); 211 void (*vmcs_delete_msr_from_vmexit_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index); 212 void (*vmcs_delete_msr_from_vmenter_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index); 213 void (*vmcs_delete_msr_from_vmexit_store_and_vmenter_load_list)(struct _VMCS_OBJECT *vmcs, UINT32 msr_index); 214 }; 215 216 void vmcs_copy(struct _VMCS_OBJECT *vmcs_dst, const struct _VMCS_OBJECT *vmcs_src); 217 void vmcs_write(struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id, UINT64 value); 218 void vmcs_write_nocheck(struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id, UINT64 value); 219 UINT64 vmcs_read(const struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id); 220 BOOLEAN vmcs_field_is_supported(VMCS_FIELD field_id); 221 222 223 INLINE void vmcs_flush_to_cpu(const struct _VMCS_OBJECT *vmcs) { 224 vmcs->vmcs_flush_to_cpu(vmcs); 225 } 226 227 INLINE void vmcs_flush_to_memory(struct _VMCS_OBJECT *vmcs) { 228 vmcs->vmcs_flush_to_memory(vmcs); 229 } 230 INLINE void vmcs_clear_dirty(const struct _VMCS_OBJECT *vmcs) { 231 vmcs->vmcs_flush_to_cpu(vmcs); 232 } 233 234 INLINE BOOLEAN vmcs_is_dirty(const struct _VMCS_OBJECT *vmcs) { 235 return vmcs->vmcs_is_dirty(vmcs); 236 } 237 238 INLINE GUEST_CPU_HANDLE vmcs_get_owner(const struct _VMCS_OBJECT *vmcs) { 239 return vmcs->vmcs_get_owner(vmcs); 240 } 241 INLINE void vmcs_destroy(struct _VMCS_OBJECT *vmcs) { 242 vmcs->vmcs_destroy(vmcs); 243 vmm_mfree(vmcs); 244 } 245 246 INLINE VMCS_LEVEL vmcs_get_level(struct _VMCS_OBJECT *vmcs) { 247 return (VMCS_LEVEL) vmcs->level; 248 } 249 250 #ifdef INCLUDE_DEAD_CODE 251 INLINE BOOLEAN vmcs_is_vmcs(struct _VMCS_OBJECT *vmcs) { 252 return VMCS_SIGNATURE == vmcs->signature; 253 } 254 INLINE UINT32 vmcs_get_storage_size(void) { 255 return sizeof(UINT64) * VMCS_FIELD_COUNT; 256 } 257 #endif 258 259 void vmcs_init_all_msr_lists(struct _VMCS_OBJECT* vmcs); 260 261 INLINE void vmcs_add_msr_to_vmexit_store_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value) { 262 vmcs->vmcs_add_msr_to_vmexit_store_list(vmcs, msr_index, value); 263 } 264 INLINE void vmcs_add_msr_to_vmexit_load_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value) { 265 vmcs->vmcs_add_msr_to_vmexit_load_list(vmcs, msr_index, value); 266 } 267 INLINE void vmcs_add_msr_to_vmenter_load_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value) { 268 vmcs->vmcs_add_msr_to_vmenter_load_list(vmcs, msr_index, value); 269 } 270 271 INLINE void vmcs_add_msr_to_vmexit_store_and_vmenter_load_lists(struct _VMCS_OBJECT *vmcs, UINT32 msr_index, UINT64 value) { 272 vmcs->vmcs_add_msr_to_vmexit_store_and_vmenter_load_list(vmcs, msr_index, value); 273 } 274 #ifdef ENABLE_LAYERING 275 INLINE void vmcs_delete_msr_from_vmexit_store_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index) { 276 vmcs->vmcs_delete_msr_from_vmexit_store_list(vmcs, msr_index); 277 } 278 279 INLINE void vmcs_delete_msr_from_vmexit_load_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index) { 280 vmcs->vmcs_delete_msr_from_vmexit_load_list(vmcs, msr_index); 281 } 282 283 INLINE void vmcs_delete_msr_from_vmenter_load_list(struct _VMCS_OBJECT *vmcs, UINT32 msr_index) { 284 vmcs->vmcs_delete_msr_from_vmenter_load_list(vmcs, msr_index); 285 } 286 287 INLINE void vmcs_delete_msr_from_vmexit_store_and_vmenter_load_lists(struct _VMCS_OBJECT *vmcs, UINT32 msr_index) { 288 vmcs->vmcs_delete_msr_from_vmexit_store_and_vmenter_load_list(vmcs, msr_index); 289 } 290 #endif 291 292 void vmcs_assign_vmexit_msr_load_list(struct _VMCS_OBJECT* vmcs, 293 UINT64 address_value, UINT64 count_value); 294 295 void vmcs_assign_vmexit_msr_load_list(struct _VMCS_OBJECT* vmcs, 296 UINT64 address_value, UINT64 count_value); 297 INLINE void vmcs_clear_vmexit_store_list(struct _VMCS_OBJECT* vmcs) { 298 vmcs_write(vmcs, VMCS_EXIT_MSR_STORE_COUNT, 0); 299 } 300 301 INLINE void vmcs_clear_vmexit_load_list(struct _VMCS_OBJECT* vmcs) { 302 vmcs_write(vmcs, VMCS_EXIT_MSR_LOAD_COUNT, 0); 303 } 304 305 INLINE void vmcs_clear_vmenter_load_list(struct _VMCS_OBJECT* vmcs) { 306 vmcs_write(vmcs, VMCS_ENTER_MSR_LOAD_COUNT, 0); 307 } 308 309 void vmcs_store(struct _VMCS_OBJECT *vmcs, UINT64 *buffer); 310 void vmcs_load(struct _VMCS_OBJECT *vmcs, UINT64 *buffer); 311 UINT32 vmcs_get_field_encoding(VMCS_FIELD field_id, RW_ACCESS *p_access); 312 void vmcs_update(struct _VMCS_OBJECT *vmcs, VMCS_FIELD field_id, 313 UINT64 value, UINT64 bits_to_update); 314 void vmcs_manager_init(void); 315 316 // is_HIGH_part is TRUE if encodign is for high part only of the VMCS field 317 VMCS_FIELD vmcs_get_field_id_by_encoding( UINT32 encoding, OPTIONAL BOOLEAN* is_HIGH_part ); 318 319 BOOLEAN vmcs_is_msr_in_vmexit_store_list(struct _VMCS_OBJECT* vmcs, UINT32 msr_index); 320 321 BOOLEAN vmcs_is_msr_in_vmexit_load_list(struct _VMCS_OBJECT* vmcs, UINT32 msr_index); 322 BOOLEAN vmcs_is_msr_in_vmenter_load_list(struct _VMCS_OBJECT* vmcs, UINT32 msr_index); 323 324 #ifdef CLI_INCLUDE 325 void vmcs_print_guest_state( const struct _VMCS_OBJECT* obj ); 326 void vmcs_print_host_state( const struct _VMCS_OBJECT* obj ); 327 void vmcs_print_controls( const struct _VMCS_OBJECT* obj ); 328 void vmcs_print_all( const struct _VMCS_OBJECT* obj ); 329 void vmcs_print_all_filtered( 330 const struct _VMCS_OBJECT* obj, UINT32 num_of_filters, char *filters[]); 331 #endif 332 const char * vmcs_get_field_name( VMCS_FIELD field_id ); 333 void vmcs_print_vmenter_msr_load_list(struct _VMCS_OBJECT* vmcs); 334 void vmcs_print_vmexit_msr_store_list(struct _VMCS_OBJECT* vmcs); 335 336 // dump vmcs to guest buffer 337 void vmcs_store_initial(GUEST_CPU_HANDLE gcpu, CPU_ID cpu_id); 338 void vmcs_restore_initial(GUEST_CPU_HANDLE gcpu); 339 void vmcs_dump_all(GUEST_CPU_HANDLE gcpu); 340 341 #endif // _VMCS_API_H_ 342