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