github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/guest/guest_cpu/guest_cpu_internal.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 _GUEST_CPU_INTERNAL_H 16 #define _GUEST_CPU_INTERNAL_H 17 18 #include "vmm_defs.h" 19 #include "guest_cpu.h" 20 #include "guest_cpu_control.h" 21 #include <common_libc.h> 22 #include "vmcs_hierarchy.h" 23 #include "vmcs_actual.h" 24 #include "emulator_if.h" 25 #include "flat_page_tables.h" 26 #include "guest_save_area.h" 27 28 29 // Guest CPU 30 // Guest CPU may be in 2 different modes: 31 // 16 mode - run under emulator 32 // any other mode - run native 33 // Defines save area for guest registers, not saved in VMCS 34 // Data structure to access IA-32 General Purpose Registers referenced by 35 // VM Exit Handlers. This is also the structure used to save/restore general 36 // purpose registers in assembly code for the VMEXIT and VMENTER handlers 37 38 #pragma PACK_ON 39 40 // Do not show to the guest the real values of the following bits + 41 // perform VMEXIT on writes to this bits 42 #define GCPU_CR4_VMM_CONTROLLED_BITS (CR4_PAE|CR4_SMXE) 43 #define GCPU_CR0_VMM_CONTROLLED_BITS 0 44 45 // main save area 46 #define CR2_SAVE_AREA IA32_REG_RSP 47 #define CR3_SAVE_AREA IA32_REG_RFLAGS 48 #define CR8_SAVE_AREA IA32_REG_RIP 49 50 #pragma PACK_OFF 51 52 typedef struct _VE_DESCRIPTOR { 53 UINT64 ve_info_hva; 54 UINT64 ve_info_hpa; 55 BOOLEAN ve_enabled; 56 UINT8 pad[4]; 57 } VE_DESCRIPTOR; 58 59 // per-cpu data/state 60 typedef struct _FVS_CPU_DESCRIPTOR { 61 UINT64 vmentry_eptp; 62 BOOLEAN enabled; 63 UINT32 padding; 64 } FVS_CPU_DESCRIPTOR; 65 66 67 // invalid CR3 value used to specify that CR3_SAVE_AREA is not up-to-date 68 #define INVALID_CR3_SAVED_VALUE UINT64_ALL_ONES 69 70 typedef struct _GUEST_CPU { 71 // save_area and vmcs must come first due to alignment. Do not move ! 72 GUEST_CPU_SAVE_AREA save_area; 73 VMCS_HIERARCHY vmcs_hierarchy; 74 GUEST_HANDLE guest_handle; 75 FPT_FLAT_PAGE_TABLES_HANDLE active_flat_pt_handle; 76 UINT64 active_flat_pt_hpa; 77 78 EMULATOR_HANDLE emulator_handle; 79 80 VIRTUAL_CPU_ID vcpu; 81 UINT8 last_guest_level; // get values from GUEST_LEVEL 82 UINT8 next_guest_level; // get values from GUEST_LEVEL 83 UINT8 state_flags; // GCPU_STATE_ENUM 84 UINT8 caching_flags; // GCPU_CACHINE_FLAGS_ENUM 85 UINT32 hw_enforcements; 86 UINT8 merge_required; 87 UINT8 cached_activity_state; // Used to determine activity state switch 88 UINT8 pad; 89 UINT8 use_host_page_tables; 90 91 GCPU_VMEXIT_CONTROLS vmexit_setup; 92 struct _GUEST_CPU *next_gcpu; 93 GCPU_RESUME_FUNC resume_func; 94 GCPU_VMEXIT_FUNC vmexit_func; 95 void *vmdb; // guest debugger handler 96 void *timer; 97 98 GPM_HANDLE active_gpm; 99 100 #ifdef FAST_VIEW_SWITCH 101 FVS_CPU_DESCRIPTOR fvs_cpu_desc; 102 #else 103 UINT8 pad1[16]; 104 #endif 105 UINT32 trigger_log_event; 106 UINT8 pad2[4]; 107 VE_DESCRIPTOR ve_desc; 108 109 } GUEST_CPU; 110 111 112 typedef enum _GCPU_STATE_ENUM { 113 GCPU_EMULATOR_FLAG = 0, // 1 - emulator is active, 0 - native 114 GCPU_FLAT_PAGES_TABLES_32_FLAG, // 1 - 32bit flat page tables in use 115 GCPU_FLAT_PAGES_TABLES_64_FLAG, // 1 - 64bit flat page tables in use 116 GCPU_ACTIVITY_STATE_CHANGED_FLAG, // 1 - Activity/Sleep state changed 117 GCPU_EXCEPTION_RESOLUTION_REQUIRED_FLAG,// 1 - VMEXIT caused by exception. Have to handle prior event injection/resume 118 GCPU_EXPLICIT_EMULATOR_REQUEST, // 1 - emulator run was requested explicitly 119 GCPU_UNRESTRICTED_GUEST_FLAG, // 1 - Unrestricted guest enabled, 0 - unrestreicted guest disabled 120 GCPU_IMPORTANT_EVENT_OCCURED_FLAG = 7, // 1 - CR0/EFER changed 121 } GCPU_STATE_ENUM; 122 123 #define SET_EMULATOR_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_EMULATOR_FLAG) 124 #define CLR_EMULATOR_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_EMULATOR_FLAG) 125 #define GET_EMULATOR_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_EMULATOR_FLAG) 126 127 #define SET_FLAT_PAGES_TABLES_32_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_32_FLAG) 128 #define CLR_FLAT_PAGES_TABLES_32_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_32_FLAG) 129 #define GET_FLAT_PAGES_TABLES_32_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_32_FLAG) 130 131 #define SET_FLAT_PAGES_TABLES_64_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_64_FLAG) 132 #define CLR_FLAT_PAGES_TABLES_64_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_64_FLAG) 133 #define GET_FLAT_PAGES_TABLES_64_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_FLAT_PAGES_TABLES_64_FLAG) 134 135 #define SET_ACTIVITY_STATE_CHANGED_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_ACTIVITY_STATE_CHANGED_FLAG) 136 #define CLR_ACTIVITY_STATE_CHANGED_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_ACTIVITY_STATE_CHANGED_FLAG) 137 #define GET_ACTIVITY_STATE_CHANGED_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_ACTIVITY_STATE_CHANGED_FLAG) 138 139 #define SET_EXCEPTION_RESOLUTION_REQUIRED_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_EXCEPTION_RESOLUTION_REQUIRED_FLAG) 140 #define CLR_EXCEPTION_RESOLUTION_REQUIRED_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_EXCEPTION_RESOLUTION_REQUIRED_FLAG) 141 #define GET_EXCEPTION_RESOLUTION_REQUIRED_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_EXCEPTION_RESOLUTION_REQUIRED_FLAG) 142 143 #define SET_EXPLICIT_EMULATOR_REQUEST_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_EXPLICIT_EMULATOR_REQUEST) 144 #define CLR_EXPLICIT_EMULATOR_REQUEST_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_EXPLICIT_EMULATOR_REQUEST) 145 #define GET_EXPLICIT_EMULATOR_REQUEST_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_EXPLICIT_EMULATOR_REQUEST) 146 147 #define SET_IMPORTANT_EVENT_OCCURED_FLAG( gcpu ) BIT_SET( (gcpu)->state_flags, GCPU_IMPORTANT_EVENT_OCCURED_FLAG) 148 #define CLR_IMPORTANT_EVENT_OCCURED_FLAG( gcpu ) BIT_CLR( (gcpu)->state_flags, GCPU_IMPORTANT_EVENT_OCCURED_FLAG) 149 #define GET_IMPORTANT_EVENT_OCCURED_FLAG( gcpu ) BIT_GET( (gcpu)->state_flags, GCPU_IMPORTANT_EVENT_OCCURED_FLAG) 150 151 #define IS_MODE_EMULATOR( gcpu ) (GET_EMULATOR_FLAG( gcpu ) == 1) 152 #define SET_MODE_EMULATOR( gcpu ) SET_EMULATOR_FLAG( gcpu ) 153 154 #ifdef ENABLE_EMULATOR 155 #define IS_MODE_NATIVE( gcpu ) ((GET_EMULATOR_FLAG( gcpu ) == 0) || \ 156 ((gcpu)->emulator_handle == NULL) || \ 157 !emul_is_running((gcpu)->emulator_handle)) 158 #else 159 #define IS_MODE_NATIVE( gcpu ) (1) 160 #endif 161 #define SET_MODE_NATIVE( gcpu ) CLR_EMULATOR_FLAG( gcpu ) 162 163 164 #define IS_FLAT_PT_INSTALLED( gcpu ) (GET_FLAT_PAGES_TABLES_32_FLAG(gcpu) || GET_FLAT_PAGES_TABLES_64_FLAG(gcpu)) 165 166 167 typedef enum _GCPU_CACHINE_FLAGS_ENUM { 168 GCPU_FX_STATE_CACHED_FLAG = 0, 169 GCPU_DEBUG_REGS_CACHED_FLAG, 170 171 GCPU_FX_STATE_MODIFIED_FLAG, 172 GCPU_DEBUG_REGS_MODIFIED_FLAG, 173 } GCPU_CACHINE_FLAGS_ENUM; 174 175 #define SET_FX_STATE_CACHED_FLAG( gcpu ) BIT_SET( (gcpu)->caching_flags, GCPU_FX_STATE_CACHED_FLAG) 176 #define CLR_FX_STATE_CACHED_FLAG( gcpu ) BIT_CLR( (gcpu)->caching_flags, GCPU_FX_STATE_CACHED_FLAG) 177 #define GET_FX_STATE_CACHED_FLAG( gcpu ) BIT_GET( (gcpu)->caching_flags, GCPU_FX_STATE_CACHED_FLAG) 178 #define SET_DEBUG_REGS_CACHED_FLAG( gcpu ) BIT_SET( (gcpu)->caching_flags, GCPU_DEBUG_REGS_CACHED_FLAG) 179 #define CLR_DEBUG_REGS_CACHED_FLAG( gcpu ) BIT_CLR( (gcpu)->caching_flags, GCPU_DEBUG_REGS_CACHED_FLAG) 180 #define GET_DEBUG_REGS_CACHED_FLAG( gcpu ) BIT_GET( (gcpu)->caching_flags, GCPU_DEBUG_REGS_CACHED_FLAG) 181 182 #define SET_FX_STATE_MODIFIED_FLAG( gcpu ) BIT_SET( (gcpu)->caching_flags, GCPU_FX_STATE_MODIFIED_FLAG) 183 #define CLR_FX_STATE_MODIFIED_FLAG( gcpu ) BIT_CLR( (gcpu)->caching_flags, GCPU_FX_STATE_MODIFIED_FLAG) 184 #define GET_FX_STATE_MODIFIED_FLAG( gcpu ) BIT_GET( (gcpu)->caching_flags, GCPU_FX_STATE_MODIFIED_FLAG) 185 186 #define SET_DEBUG_REGS_MODIFIED_FLAG( gcpu ) BIT_SET( (gcpu)->caching_flags, GCPU_DEBUG_REGS_MODIFIED_FLAG) 187 #define CLR_DEBUG_REGS_MODIFIED_FLAG( gcpu ) BIT_CLR( (gcpu)->caching_flags, GCPU_DEBUG_REGS_MODIFIED_FLAG) 188 #define GET_DEBUG_REGS_MODIFIED_FLAG( gcpu ) BIT_GET( (gcpu)->caching_flags, GCPU_DEBUG_REGS_MODIFIED_FLAG) 189 190 #define SET_ALL_MODIFIED( gcpu ) {(gcpu)->caching_flags = (UINT8)-1;} 191 #define CLR_ALL_CACHED( gcpu ) {(gcpu)->caching_flags = 0;} 192 193 194 // this is a shortcut pointer for assembler code 195 extern GUEST_CPU_SAVE_AREA** g_guest_regs_save_area; 196 197 void cache_debug_registers( const GUEST_CPU* gcpu ); 198 void cache_fx_state( const GUEST_CPU* gcpu ); 199 #ifdef INCLUDE_UNUSED_CODE 200 void restore_hw_debug_registers( GUEST_CPU* gcpu ); 201 void restore_fx_state( GUEST_CPU* gcpu ); 202 #endif 203 204 INLINE UINT64 gcpu_get_msr_reg_internal( const GUEST_CPU_HANDLE gcpu, 205 VMM_IA32_MODEL_SPECIFIC_REGISTERS reg ) 206 { 207 return gcpu_get_msr_reg_internal_layered(gcpu, reg, VMCS_MERGED); 208 } 209 210 #define SET_CACHED_ACTIVITY_STATE( __gcpu, __value ) \ 211 { (__gcpu)->cached_activity_state = (UINT8)(__value); } 212 213 #define GET_CACHED_ACTIVITY_STATE( __gcpu ) \ 214 ((IA32_VMX_VMCS_GUEST_SLEEP_STATE)((__gcpu)->cached_activity_state)) 215 216 #define IS_STATE_INACTIVE( activity_state ) \ 217 (Ia32VmxVmcsGuestSleepStateWaitForSipi == (activity_state)) 218 219 #endif // _GUEST_CPU_INTERNAL_H