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