github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/host/hw/vmcs_init.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 "vmcs_init.h"
    16  #include "vmx_ctrl_msrs.h"
    17  #include "vmx_vmcs.h"
    18  #include "vmm_phys_mem_types.h"
    19  #include "hw_utils.h"
    20  #include "heap.h"
    21  #include "libc.h"
    22  #include "gpm_api.h"
    23  #include "host_memory_manager_api.h"
    24  #include "host_cpu.h"
    25  #include "hw_vmx_utils.h"
    26  #include "vmm_dbg.h"
    27  #include "file_codes.h"
    28  #define VMM_DEADLOOP()          VMM_DEADLOOP_LOG(VMCS_INIT_C)
    29  #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(VMCS_INIT_C, __condition)
    30  #ifdef JLMDEBUG
    31  #include "jlmdebug.h"
    32  #endif
    33  
    34  #define MAX_32BIT_NUMBER 0x0FFFFFFFF
    35  #define MASK_PE_PG_OFF_UNRESTRICTED_GUEST 0xFFFFFFFF7FFFFFFE
    36  
    37  
    38  // Initialization of the VMCS
    39  static IA32_VMX_CAPABILITIES g_vmx_capabilities;
    40  void* g_vmx_capabilities_ptr = &g_vmx_capabilities;
    41  static VMCS_HW_CONSTRAINTS   g_vmx_constraints;
    42  static VMCS_HW_FIXED         g_vmx_fixed;
    43  VMCS_HW_FIXED* gp_vmx_fixed = &g_vmx_fixed;
    44  UINT64 g_vmx_fixed_1_cr0_save;
    45  
    46  static BOOLEAN g_init_done = FALSE;
    47  
    48  void print_vmx_capabilities( void );
    49  
    50  
    51  // #define VMCS_REGION_SIZE g_vmx_capabilities.VmcsRevisionIdentifier.Bits.VmcsRegionSize
    52  #define VMCS_REGION_SIZE (g_vmx_capabilities.VmcsRevisionIdentifier.Uint64&0x77777777)
    53  #define VMCS_ABOVE_4G_SUPPORTED                                                 \
    54      (g_vmx_capabilities.VmcsRevisionIdentifier.Bits.PhysicalAddressWidth != 1)
    55  #define VMCS_MAX_SIZE_OF_MSR_LISTS                                              \
    56      (g_vmx_capabilities.MiscellaneousData.Bits.MsrListsMaxSize + 1)*512
    57  #define VMCS_MEMORY_TYPE    vmcs_memory_type()
    58  #define VMCS_REVISION g_vmx_capabilities.VmcsRevisionIdentifier.Bits.RevisionIdentifier
    59  
    60  #ifdef DEBUG
    61  #define VMCS_FIXED_BIT_2_CHAR( field_name, bit_name )                           \
    62      fx_bit_2_char(g_vmx_fixed.fixed_0_ ## field_name .Bits. bit_name,        \
    63                    g_vmx_fixed.fixed_1_ ## field_name .Bits. bit_name)
    64  
    65  INLINE char fx_bit_2_char( UINT32 mb0, UINT32 mb1 )
    66  {
    67      return (mb0 != mb1) ? 'X' : (mb0 == 0) ? '0' : '1';
    68  }
    69  #endif
    70  
    71  #define CAP_BIT_TO_CHAR( field_name, bit_name ) ((g_vmx_capabilities.field_name).Bits.bit_name + '0')
    72  
    73  
    74  static void fill_vmx_capabilities( void )
    75  {
    76  #ifdef JLMDEBUG1
    77      bprint("At fill_vmx_capabilities 0x%016x\n", 
    78              g_vmx_capabilities.VmcsRevisionIdentifier.Uint64);
    79  #endif
    80      g_vmx_capabilities.VmcsRevisionIdentifier.Uint64 = 
    81              hw_read_msr(IA32_MSR_VMCS_REVISION_IDENTIFIER_INDEX);
    82      g_vmx_capabilities.PinBasedVmExecutionControls.Uint64 = 
    83              hw_read_msr(IA32_MSR_PIN_BASED_VM_EXECUTION_CONTROLS_INDEX);
    84      g_vmx_capabilities.ProcessorBasedVmExecutionControls.Uint64 = 
    85              hw_read_msr(IA32_MSR_PROCESSOR_BASED_VM_EXECUTION_CONTROLS_INDEX);
    86      g_vmx_capabilities.EptVpidCapabilities.Uint64 = 0;
    87  
    88      if (g_vmx_capabilities.ProcessorBasedVmExecutionControls.Bits.MayBeSetToOne.Bits.SecondaryControls) {
    89          g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Uint64= 
    90              hw_read_msr(IA32_MSR_PROCESSOR_BASED_VM_EXECUTION_CONTROLS2_INDEX);
    91  
    92          if (g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.EnableEPT
    93              || g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.EnableVPID) {
    94              g_vmx_capabilities.EptVpidCapabilities.Uint64 = 
    95              hw_read_msr(IA32_MSR_EPT_VPID_CAP_INDEX);
    96          }
    97      }
    98      g_vmx_capabilities.VmExitControls.Uint64 = 
    99                  hw_read_msr(IA32_MSR_VM_EXIT_CONTROLS_INDEX);
   100      g_vmx_capabilities.VmEntryControls.Uint64 = hw_read_msr(IA32_MSR_VM_ENTRY_CONTROLS_INDEX);
   101      g_vmx_capabilities.MiscellaneousData.Uint64 = 
   102                  hw_read_msr(IA32_MSR_MISCELLANEOUS_DATA_INDEX);
   103      g_vmx_capabilities.Cr0MayBeSetToZero.Uint64 = 
   104                  hw_read_msr(IA32_MSR_CR0_ALLOWED_ZERO_INDEX);
   105      g_vmx_capabilities.Cr0MayBeSetToOne.Uint64  = 
   106                  hw_read_msr(IA32_MSR_CR0_ALLOWED_ONE_INDEX);
   107      g_vmx_capabilities.Cr4MayBeSetToZero.Uint64 = 
   108                  hw_read_msr(IA32_MSR_CR4_ALLOWED_ZERO_INDEX);
   109      g_vmx_capabilities.Cr4MayBeSetToOne.Uint64  = 
   110                  hw_read_msr(IA32_MSR_CR4_ALLOWED_ONE_INDEX);
   111  
   112      VMM_ASSERT( VMCS_REGION_SIZE != 0 );
   113      g_vmx_constraints.may1_pin_based_exec_ctrl.Uint32 = 
   114            g_vmx_capabilities.PinBasedVmExecutionControls.Bits.MayBeSetToOne.Uint32;
   115      g_vmx_constraints.may0_pin_based_exec_ctrl.Uint32 = 
   116            g_vmx_capabilities.PinBasedVmExecutionControls.Bits.MayBeSetToZero.Uint32;
   117      g_vmx_constraints.may1_processor_based_exec_ctrl.Uint32 = 
   118            g_vmx_capabilities.ProcessorBasedVmExecutionControls.Bits.MayBeSetToOne.Uint32;
   119      g_vmx_constraints.may0_processor_based_exec_ctrl.Uint32 = 
   120            g_vmx_capabilities.ProcessorBasedVmExecutionControls.Bits.MayBeSetToZero.Uint32;
   121      g_vmx_constraints.may1_processor_based_exec_ctrl2.Uint32 = 
   122            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Uint32;
   123      g_vmx_constraints.may0_processor_based_exec_ctrl2.Uint32 = 
   124            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToZero.Uint32;
   125      g_vmx_constraints.may1_vm_exit_ctrl.Uint32 = 
   126            g_vmx_capabilities.VmExitControls.Bits.MayBeSetToOne.Uint32;
   127      g_vmx_constraints.may0_vm_exit_ctrl.Uint32 = 
   128            g_vmx_capabilities.VmExitControls.Bits.MayBeSetToZero.Uint32;
   129      g_vmx_constraints.may1_vm_entry_ctrl.Uint32 = 
   130            g_vmx_capabilities.VmEntryControls.Bits.MayBeSetToOne.Uint32;
   131      g_vmx_constraints.may0_vm_entry_ctrl.Uint32 = 
   132            g_vmx_capabilities.VmEntryControls.Bits.MayBeSetToZero.Uint32;
   133      g_vmx_constraints.may1_cr0.Uint64 = g_vmx_capabilities.Cr0MayBeSetToOne.Uint64;
   134      g_vmx_constraints.may0_cr0.Uint64 = g_vmx_capabilities.Cr0MayBeSetToZero.Uint64;
   135      g_vmx_constraints.may1_cr4.Uint64 = g_vmx_capabilities.Cr4MayBeSetToOne.Uint64;
   136      g_vmx_constraints.may0_cr4.Uint64 = g_vmx_capabilities.Cr4MayBeSetToZero.Uint64;
   137      g_vmx_constraints.number_of_cr3_target_values = 
   138            g_vmx_capabilities.MiscellaneousData.Bits.NumberOfCr3TargetValues;
   139      g_vmx_constraints.max_msr_lists_size_in_bytes= VMCS_MAX_SIZE_OF_MSR_LISTS;
   140      g_vmx_constraints.vmx_timer_length  = g_vmx_capabilities.MiscellaneousData.Bits.PreemptionTimerLength;
   141      g_vmx_constraints.vmcs_revision  = VMCS_REVISION;
   142      g_vmx_constraints.mseg_revision_id = 
   143            g_vmx_capabilities.MiscellaneousData.Bits.MsegRevisionIdentifier;
   144      g_vmx_constraints.vm_entry_in_halt_state_supported = 
   145            g_vmx_capabilities.MiscellaneousData.Bits.EntryInHaltStateSupported;
   146      g_vmx_constraints.vm_entry_in_shutdown_state_supported  = 
   147            g_vmx_capabilities.MiscellaneousData.Bits.EntryInShutdownStateSupported;
   148      g_vmx_constraints.vm_entry_in_wait_for_sipi_state_supported = 
   149            g_vmx_capabilities.MiscellaneousData.Bits.EntryInWaitForSipiStateSupported;
   150      g_vmx_constraints.processor_based_exec_ctrl2_supported = 
   151            g_vmx_capabilities.ProcessorBasedVmExecutionControls.Bits.MayBeSetToOne.Bits.SecondaryControls;
   152      g_vmx_constraints.ept_supported = 
   153            g_vmx_constraints.processor_based_exec_ctrl2_supported &&
   154            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.EnableEPT;
   155      g_vmx_constraints.unrestricted_guest_supported = 
   156            g_vmx_constraints.processor_based_exec_ctrl2_supported &&
   157            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.UnrestrictedGuest;
   158      g_vmx_constraints.vpid_supported = g_vmx_constraints.processor_based_exec_ctrl2_supported &&
   159            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.EnableVPID;
   160  #ifdef FAST_VIEW_SWITCH
   161      g_vmx_constraints.vmfunc_supported  = 
   162            g_vmx_constraints.processor_based_exec_ctrl2_supported &&
   163            g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.Vmfunc;
   164      if ( g_vmx_constraints.vmfunc_supported ) {
   165          g_vmx_capabilities.VmFuncControls.Uint64 = 
   166                  hw_read_msr(IA32_MSR_VMX_VMFUNC_CTRL);
   167          VMM_LOG(mask_anonymous, level_trace,"VmFuncCtrl                                   = %18P\n",g_vmx_capabilities.VmFuncControls.Uint64);
   168          if( g_vmx_capabilities.VmFuncControls.Bits.EptpSwitching ) {
   169              g_vmx_constraints.eptp_switching_supported = g_vmx_constraints.vmfunc_supported && g_vmx_capabilities.VmFuncControls.Bits.EptpSwitching ;
   170              VMM_LOG(mask_anonymous, level_trace,"EPTP switching supported...");
   171          }
   172      }
   173  #endif
   174      g_vmx_constraints.ve_supported  = 
   175                  g_vmx_constraints.processor_based_exec_ctrl2_supported &&
   176                  g_vmx_capabilities.ProcessorBasedVmExecutionControls2.Bits.MayBeSetToOne.Bits.VE;
   177      if (g_vmx_constraints.ve_supported) {
   178      	VMM_LOG(mask_anonymous, level_trace,"VE supported...\n");
   179      }
   180      g_vmx_constraints.ept_vpid_capabilities = g_vmx_capabilities.EptVpidCapabilities;
   181  
   182      // determine fixed values
   183      g_vmx_fixed.fixed_1_pin_based_exec_ctrl.Uint32= 
   184                  g_vmx_constraints.may0_pin_based_exec_ctrl.Uint32&
   185                  g_vmx_constraints.may1_pin_based_exec_ctrl.Uint32;
   186      g_vmx_fixed.fixed_0_pin_based_exec_ctrl.Uint32= 
   187                  g_vmx_constraints.may0_pin_based_exec_ctrl.Uint32|
   188                  g_vmx_constraints.may1_pin_based_exec_ctrl.Uint32;
   189      g_vmx_fixed.fixed_1_processor_based_exec_ctrl.Uint32 =
   190                  g_vmx_constraints.may0_processor_based_exec_ctrl.Uint32 &
   191                  g_vmx_constraints.may1_processor_based_exec_ctrl.Uint32;
   192      g_vmx_fixed.fixed_0_processor_based_exec_ctrl.Uint32 =
   193                  g_vmx_constraints.may0_processor_based_exec_ctrl.Uint32 |
   194                  g_vmx_constraints.may1_processor_based_exec_ctrl.Uint32;
   195      g_vmx_fixed.fixed_1_processor_based_exec_ctrl2.Uint32 =
   196                  g_vmx_constraints.may0_processor_based_exec_ctrl2.Uint32 &
   197                  g_vmx_constraints.may1_processor_based_exec_ctrl2.Uint32;
   198      g_vmx_fixed.fixed_0_processor_based_exec_ctrl2.Uint32 =
   199                  g_vmx_constraints.may0_processor_based_exec_ctrl2.Uint32 |
   200                  g_vmx_constraints.may1_processor_based_exec_ctrl2.Uint32;
   201      g_vmx_fixed.fixed_1_vm_exit_ctrl.Uint32 = 
   202                  g_vmx_constraints.may0_vm_exit_ctrl.Uint32 &
   203                  g_vmx_constraints.may1_vm_exit_ctrl.Uint32;
   204      g_vmx_fixed.fixed_0_vm_exit_ctrl.Uint32 = 
   205                  g_vmx_constraints.may0_vm_exit_ctrl.Uint32 |
   206                  g_vmx_constraints.may1_vm_exit_ctrl.Uint32;
   207      g_vmx_fixed.fixed_1_vm_entry_ctrl.Uint32= 
   208                  g_vmx_constraints.may0_vm_entry_ctrl.Uint32 &
   209                  g_vmx_constraints.may1_vm_entry_ctrl.Uint32;
   210      g_vmx_fixed.fixed_0_vm_entry_ctrl.Uint32= 
   211                  g_vmx_constraints.may0_vm_entry_ctrl.Uint32 |
   212                  g_vmx_constraints.may1_vm_entry_ctrl.Uint32;
   213      g_vmx_fixed.fixed_1_cr0.Uint64  = g_vmx_constraints.may0_cr0.Uint64 &
   214                                        g_vmx_constraints.may1_cr0.Uint64;
   215      // If unrestricted guest is supported FIXED1 value should not have PG and PE 
   216      if (g_vmx_constraints.unrestricted_guest_supported){
   217      	g_vmx_fixed.fixed_1_cr0.Uint64 &= MASK_PE_PG_OFF_UNRESTRICTED_GUEST;
   218      }
   219      g_vmx_fixed.fixed_0_cr0.Uint64  = g_vmx_constraints.may0_cr0.Uint64 |
   220                                        g_vmx_constraints.may1_cr0.Uint64;
   221      g_vmx_fixed.fixed_1_cr4.Uint64 = g_vmx_constraints.may0_cr4.Uint64 &
   222                                                g_vmx_constraints.may1_cr4.Uint64;
   223      g_vmx_fixed.fixed_0_cr4.Uint64 = g_vmx_constraints.may0_cr4.Uint64 |
   224                                       g_vmx_constraints.may1_cr4.Uint64;
   225  #ifdef JLMDEBUG1
   226     bprint(" fixed_0_cr0 fixed_1_cr0 fixed_0_cr4 fixed_1_cr4: 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
   227           g_vmx_fixed.fixed_0_cr0.Uint64, g_vmx_fixed.fixed_1_cr0.Uint64,
   228           g_vmx_fixed.fixed_0_cr4.Uint64, g_vmx_fixed.fixed_1_cr4.Uint64);
   229     bprint("gp_vmx_fixed: 0x%016lx\n", gp_vmx_fixed);
   230     bprint("Revision Identifiers 0x%016x\n", 
   231              g_vmx_capabilities.VmcsRevisionIdentifier.Uint64);
   232  #endif
   233      VMM_DEBUG_CODE( print_vmx_capabilities() );
   234  }
   235  
   236  INLINE VMM_PHYS_MEM_TYPE vmcs_memory_type( void )
   237  {
   238      switch (g_vmx_capabilities.VmcsRevisionIdentifier.Bits.VmcsMemoryType) {
   239          case 0: return( VMM_PHYS_MEM_UNCACHABLE );
   240          case 6: return( VMM_PHYS_MEM_WRITE_BACK );
   241          default:;
   242      }
   243  
   244      VMM_LOG(mask_anonymous, level_trace,"FATAL: Unsupported memory type for VMCS region in IA32_VMX_CAPABILITIES\n");
   245      VMM_ASSERT( FALSE );
   246      return VMM_PHYS_MEM_UNDEFINED;
   247  }
   248  #ifdef DEBUG
   249  // Print capabilities
   250  static void print_vmx_capabilities( void )
   251  {
   252      VMM_LOG(mask_anonymous, level_trace,"\n");
   253      VMM_LOG(mask_anonymous, level_trace,"---------------- Discovered VMX capabilities --------------\n");
   254      VMM_LOG(mask_anonymous, level_trace,"Legend:\n");
   255      VMM_LOG(mask_anonymous, level_trace,"    X - may  be set to 0 or 1\n");
   256      VMM_LOG(mask_anonymous, level_trace,"    0 - must be set to 0\n");
   257      VMM_LOG(mask_anonymous, level_trace,"    1 - must be set to 1\n");
   258  
   259      VMM_LOG(mask_anonymous, level_trace,"\n");
   260      VMM_LOG(mask_anonymous, level_trace,"Raw data values\n");
   261      VMM_LOG(mask_anonymous, level_trace,"===================================================== ==========================\n");
   262      VMM_LOG(mask_anonymous, level_trace,"VmcsRevisionIdentifier                              = %18P\n",g_vmx_capabilities.VmcsRevisionIdentifier.Uint64);
   263      VMM_LOG(mask_anonymous, level_trace,"PinBasedVmExecutionControls - may be set to 0       = %P\n",g_vmx_constraints.may0_pin_based_exec_ctrl.Uint32);
   264      VMM_LOG(mask_anonymous, level_trace,"PinBasedVmExecutionControls - may be set to 1       = %P\n",g_vmx_constraints.may1_pin_based_exec_ctrl.Uint32);
   265      VMM_LOG(mask_anonymous, level_trace,"ProcessorBasedVmExecutionControls - may be set to 0 = %P\n",g_vmx_constraints.may0_processor_based_exec_ctrl.Uint32);
   266      VMM_LOG(mask_anonymous, level_trace,"ProcessorBasedVmExecutionControls - may be set to 1 = %P\n",g_vmx_constraints.may1_processor_based_exec_ctrl.Uint32);
   267      VMM_LOG(mask_anonymous, level_trace,"ProcessorBasedVmExecutionControls2 - may be set to 0= %P\n",g_vmx_constraints.may0_processor_based_exec_ctrl2.Uint32);
   268      VMM_LOG(mask_anonymous, level_trace,"ProcessorBasedVmExecutionControls2 - may be set to 1= %P\n",g_vmx_constraints.may1_processor_based_exec_ctrl2.Uint32);
   269      VMM_LOG(mask_anonymous, level_trace,"VmExitControls - may be set to 0                    = %P\n",g_vmx_constraints.may0_vm_exit_ctrl.Uint32);
   270      VMM_LOG(mask_anonymous, level_trace,"VmExitControls - may be set to 1                    = %P\n",g_vmx_constraints.may1_vm_exit_ctrl.Uint32);
   271      VMM_LOG(mask_anonymous, level_trace,"VmEntryControls - may be set to 0                   = %P\n",g_vmx_constraints.may0_vm_entry_ctrl.Uint32);
   272      VMM_LOG(mask_anonymous, level_trace,"VmEntryControls - may be set to 1                   = %P\n",g_vmx_constraints.may1_vm_entry_ctrl.Uint32);
   273      VMM_LOG(mask_anonymous, level_trace,"MiscellaneousData                                   = %18P\n",g_vmx_capabilities.MiscellaneousData.Uint64);
   274      VMM_LOG(mask_anonymous, level_trace,"Cr0MayBeSetToZero                                   = %18P\n",g_vmx_capabilities.Cr0MayBeSetToZero.Uint64);
   275      VMM_LOG(mask_anonymous, level_trace,"Cr0MayBeSetToOne                                    = %18P\n",g_vmx_capabilities.Cr0MayBeSetToOne.Uint64);
   276      VMM_LOG(mask_anonymous, level_trace,"Cr4MayBeSetToZero                                   = %18P\n",g_vmx_capabilities.Cr4MayBeSetToZero.Uint64);
   277      VMM_LOG(mask_anonymous, level_trace,"Cr4MayBeSetToOne                                    = %18P\n",g_vmx_capabilities.Cr4MayBeSetToOne.Uint64);
   278      VMM_LOG(mask_anonymous, level_trace,"EptVPIDCapabilities                                 = %18P\n",g_vmx_capabilities.EptVpidCapabilities.Uint64);
   279  
   280      VMM_LOG(mask_anonymous, level_trace,"\n");
   281      VMM_LOG(mask_anonymous, level_trace,"Global data                                 Values\n");
   282      VMM_LOG(mask_anonymous, level_trace,"========================================= ===================\n");
   283      VMM_LOG(mask_anonymous, level_trace,"VMCS Revision Identifier                  = 0x%08X\n",    g_vmx_capabilities.VmcsRevisionIdentifier.Bits.RevisionIdentifier);
   284      VMM_LOG(mask_anonymous, level_trace,"VMCS Region Size                          = %d bytes\n",  g_vmx_capabilities.VmcsRevisionIdentifier.Bits.VmcsRegionSize);
   285      VMM_LOG(mask_anonymous, level_trace,"Physical Address Width                    = %d\n",        g_vmx_capabilities.VmcsRevisionIdentifier.Bits.PhysicalAddressWidth);
   286      VMM_LOG(mask_anonymous, level_trace,"Dual Monitor SMIs                         = %d\n",        g_vmx_capabilities.VmcsRevisionIdentifier.Bits.DualMonitorSystemManagementInterrupts);
   287      VMM_LOG(mask_anonymous, level_trace,"VMCS memory type                          = %s (%d)\n",        (vmcs_memory_type() == VMM_PHYS_MEM_UNCACHABLE) ? "UC" : "WB",  vmcs_memory_type());
   288      VMM_LOG(mask_anonymous, level_trace,"VMCS Instr Info on IO is Valid            = %c\n",        g_vmx_capabilities.VmcsRevisionIdentifier.Bits.VmcsInstructionInfoFieldOnIOisValid + '0' );
   289      VMM_LOG(mask_anonymous, level_trace,"VMX Timer Length                          = %d TSC ticks\n",  1 << g_vmx_capabilities.MiscellaneousData.Bits.PreemptionTimerLength);
   290      VMM_LOG(mask_anonymous, level_trace,"VmEntry in HLT State Supported            = %c\n",        g_vmx_constraints.vm_entry_in_halt_state_supported + '0');
   291      VMM_LOG(mask_anonymous, level_trace,"VmEntry in SHUTDOWN State Supported       = %c\n",        g_vmx_constraints.vm_entry_in_shutdown_state_supported + '0');
   292      VMM_LOG(mask_anonymous, level_trace,"VmEntry in Wait-For-SIPI State Supported  = %c\n",        g_vmx_constraints.vm_entry_in_wait_for_sipi_state_supported + '0');
   293      VMM_LOG(mask_anonymous, level_trace,"Number of CR3 Target Values               = %d\n",        g_vmx_constraints.number_of_cr3_target_values);
   294      VMM_LOG(mask_anonymous, level_trace,"Max Size of MSR Lists                     = %d bytes\n",  g_vmx_constraints.max_msr_lists_size_in_bytes);
   295      VMM_LOG(mask_anonymous, level_trace,"MSEG Revision Identifier                  = 0x%08x\n",    g_vmx_capabilities.MiscellaneousData.Bits.MsegRevisionIdentifier);
   296  
   297      VMM_LOG(mask_anonymous, level_trace,"\n");
   298      VMM_LOG(mask_anonymous, level_trace,"Pin-Based VM Execution Controls        Value\n");
   299      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   300      VMM_LOG(mask_anonymous, level_trace,"ExternalInterrupt                        %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, ExternalInterrupt ));
   301      VMM_LOG(mask_anonymous, level_trace,"HostInterrupt                            %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, HostInterrupt     ));
   302      VMM_LOG(mask_anonymous, level_trace,"Init                                     %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, Init              ));
   303      VMM_LOG(mask_anonymous, level_trace,"Nmi                                      %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, Nmi               ));
   304      VMM_LOG(mask_anonymous, level_trace,"Sipi                                     %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, Sipi              ));
   305      VMM_LOG(mask_anonymous, level_trace,"VirtualNmi                               %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, VirtualNmi        ));
   306      VMM_LOG(mask_anonymous, level_trace,"VmxTimer                                 %c\n",VMCS_FIXED_BIT_2_CHAR( pin_based_exec_ctrl, VmxTimer          ));
   307  
   308      VMM_LOG(mask_anonymous, level_trace,"\n");
   309      VMM_LOG(mask_anonymous, level_trace,"Processor-Based VM Execution Controls  Value\n");
   310      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   311      VMM_LOG(mask_anonymous, level_trace,"SoftwareInterrupt                        %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, SoftwareInterrupt));
   312      VMM_LOG(mask_anonymous, level_trace,"TripleFault                              %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, TripleFault      ));
   313      VMM_LOG(mask_anonymous, level_trace,"VirtualInterrupt                         %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, VirtualInterrupt ));
   314      VMM_LOG(mask_anonymous, level_trace,"UseTscOffsetting                         %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, UseTscOffsetting ));
   315      VMM_LOG(mask_anonymous, level_trace,"TaskSwitch                               %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, TaskSwitch       ));
   316      VMM_LOG(mask_anonymous, level_trace,"Cpuid                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Cpuid            ));
   317      VMM_LOG(mask_anonymous, level_trace,"GetSec                                   %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, GetSec           ));
   318      VMM_LOG(mask_anonymous, level_trace,"Hlt                                      %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Hlt              ));
   319      VMM_LOG(mask_anonymous, level_trace,"Invd                                     %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Invd             ));
   320      VMM_LOG(mask_anonymous, level_trace,"Invlpg                                   %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Invlpg           ));
   321      VMM_LOG(mask_anonymous, level_trace,"Mwait                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Mwait            ));
   322      VMM_LOG(mask_anonymous, level_trace,"Rdpmc                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Rdpmc            ));
   323      VMM_LOG(mask_anonymous, level_trace,"Rdtsc                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Rdtsc            ));
   324      VMM_LOG(mask_anonymous, level_trace,"Rsm                                      %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Rsm              ));
   325      VMM_LOG(mask_anonymous, level_trace,"VmInstruction                            %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, VmInstruction    ));
   326      VMM_LOG(mask_anonymous, level_trace,"Cr3Load                                  %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Cr3Load          ));
   327      VMM_LOG(mask_anonymous, level_trace,"Cr3Store                                 %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Cr3Store         ));
   328      VMM_LOG(mask_anonymous, level_trace,"UseCr3Mask                               %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, UseCr3Mask       ));
   329      VMM_LOG(mask_anonymous, level_trace,"UseCr3ReadShadow                         %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, UseCr3ReadShadow ));
   330      VMM_LOG(mask_anonymous, level_trace,"Cr8Load                                  %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Cr8Load          ));
   331      VMM_LOG(mask_anonymous, level_trace,"Cr8Store                                 %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Cr8Store         ));
   332      VMM_LOG(mask_anonymous, level_trace,"TprShadow                                %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, TprShadow        ));
   333      VMM_LOG(mask_anonymous, level_trace,"NmiWindow                                %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, NmiWindow        ));
   334      VMM_LOG(mask_anonymous, level_trace,"MovDr                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, MovDr            ));
   335      VMM_LOG(mask_anonymous, level_trace,"UnconditionalIo                          %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, UnconditionalIo  ));
   336      VMM_LOG(mask_anonymous, level_trace,"ActivateIoBitmaps                        %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, ActivateIoBitmaps));
   337      VMM_LOG(mask_anonymous, level_trace,"MsrProtection                            %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, MsrProtection    ));
   338      VMM_LOG(mask_anonymous, level_trace,"MonitorTrapFlag                          %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, MonitorTrapFlag  ));
   339      VMM_LOG(mask_anonymous, level_trace,"UseMsrBitmaps                            %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, UseMsrBitmaps    ));
   340      VMM_LOG(mask_anonymous, level_trace,"Monitor                                  %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Monitor          ));
   341      VMM_LOG(mask_anonymous, level_trace,"Pause                                    %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, Pause            ));
   342      VMM_LOG(mask_anonymous, level_trace,"SecondaryControls                        %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl, SecondaryControls));
   343  
   344      VMM_LOG(mask_anonymous, level_trace,"\n");
   345      VMM_LOG(mask_anonymous, level_trace,"Processor-Based VM Execution Controls2  Value\n");
   346      VMM_LOG(mask_anonymous, level_trace,"(Valid only if SecondaryControls is not fixed 0)\n");
   347      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   348      VMM_LOG(mask_anonymous, level_trace,"VirtualizeAPIC                           %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, VirtualizeAPIC ));
   349      VMM_LOG(mask_anonymous, level_trace,"EnableEPT                                %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, EnableEPT ));
   350      VMM_LOG(mask_anonymous, level_trace,"Unrestricted Guest                       %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, UnrestrictedGuest ));
   351      VMM_LOG(mask_anonymous, level_trace,"DescriptorTableExiting                   %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, DescriptorTableExiting ));
   352      VMM_LOG(mask_anonymous, level_trace,"EnableRDTSCP                             %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, EnableRDTSCP ));
   353      VMM_LOG(mask_anonymous, level_trace,"EnableINVPCID                            %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, EnableINVPCID ));
   354      VMM_LOG(mask_anonymous, level_trace,"ShadowApicMsrs                           %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, ShadowApicMsrs ));
   355      VMM_LOG(mask_anonymous, level_trace,"EnableVPID                               %c\n",VMCS_FIXED_BIT_2_CHAR( processor_based_exec_ctrl2, EnableVPID ));
   356  
   357      VMM_LOG(mask_anonymous, level_trace,"\n");
   358      VMM_LOG(mask_anonymous, level_trace,"VM Exit Controls                       Value\n");
   359      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   360      VMM_LOG(mask_anonymous, level_trace,"SaveCr0AndCr4                            %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveCr0AndCr4                  ));
   361      VMM_LOG(mask_anonymous, level_trace,"SaveCr3                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveCr3                        ));
   362      VMM_LOG(mask_anonymous, level_trace,"SaveDebugControls                        %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveDebugControls              ));
   363      VMM_LOG(mask_anonymous, level_trace,"SaveSegmentRegisters                     %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveSegmentRegisters           ));
   364      VMM_LOG(mask_anonymous, level_trace,"SaveEspEipEflags                         %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveEspEipEflags               ));
   365      VMM_LOG(mask_anonymous, level_trace,"SavePendingDebugExceptions               %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SavePendingDebugExceptions     ));
   366      VMM_LOG(mask_anonymous, level_trace,"SaveInterruptibilityInformation          %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveInterruptibilityInformation));
   367      VMM_LOG(mask_anonymous, level_trace,"SaveActivityState                        %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveActivityState              ));
   368      VMM_LOG(mask_anonymous, level_trace,"SaveWorkingVmcsPointer                   %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveWorkingVmcsPointer         ));
   369      VMM_LOG(mask_anonymous, level_trace,"Ia32eModeHost                            %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, Ia32eModeHost                  ));
   370      VMM_LOG(mask_anonymous, level_trace,"LoadCr0AndCr4                            %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadCr0AndCr4                  ));
   371      VMM_LOG(mask_anonymous, level_trace,"LoadCr3                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadCr3                        ));
   372      VMM_LOG(mask_anonymous, level_trace,"LoadSegmentRegisters                     %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadSegmentRegisters           ));
   373      VMM_LOG(mask_anonymous, level_trace,"LoadEspEip                               %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadEspEip                     ));
   374      VMM_LOG(mask_anonymous, level_trace,"AcknowledgeInterruptOnExit               %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, AcknowledgeInterruptOnExit     ));
   375      VMM_LOG(mask_anonymous, level_trace,"SaveSysEnterMsrs                         %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveSysEnterMsrs               ));
   376      VMM_LOG(mask_anonymous, level_trace,"LoadSysEnterMsrs                         %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadSysEnterMsrs               ));
   377      VMM_LOG(mask_anonymous, level_trace,"SavePat                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SavePat                        ));
   378      VMM_LOG(mask_anonymous, level_trace,"LoadPat                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadPat                        ));
   379      VMM_LOG(mask_anonymous, level_trace,"SaveEfer                                 %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveEfer                       ));
   380      VMM_LOG(mask_anonymous, level_trace,"LoadEfer                                 %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, LoadEfer                       ));
   381      VMM_LOG(mask_anonymous, level_trace,"SaveVmxTimer                             %c\n",VMCS_FIXED_BIT_2_CHAR( vm_exit_ctrl, SaveVmxTimer                   ));
   382  
   383      VMM_LOG(mask_anonymous, level_trace,"\n");
   384      VMM_LOG(mask_anonymous, level_trace,"VM Entry Controls                      Value\n");
   385      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   386      VMM_LOG(mask_anonymous, level_trace,"LoadCr0AndCr4                            %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadCr0AndCr4                  ));
   387      VMM_LOG(mask_anonymous, level_trace,"LoadCr3                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadCr3                        ));
   388      VMM_LOG(mask_anonymous, level_trace,"LoadDebugControls                        %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadDebugControls              ));
   389      VMM_LOG(mask_anonymous, level_trace,"LoadSegmentRegisters                     %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadSegmentRegisters           ));
   390      VMM_LOG(mask_anonymous, level_trace,"LoadEspEipEflags                         %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadEspEipEflags               ));
   391      VMM_LOG(mask_anonymous, level_trace,"LoadPendingDebugExceptions               %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadPendingDebugExceptions     ));
   392      VMM_LOG(mask_anonymous, level_trace,"LoadInterruptibilityInformation          %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadInterruptibilityInformation));
   393      VMM_LOG(mask_anonymous, level_trace,"LoadActivityState                        %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadActivityState              ));
   394      VMM_LOG(mask_anonymous, level_trace,"LoadWorkingVmcsPointer                   %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadWorkingVmcsPointer         ));
   395      VMM_LOG(mask_anonymous, level_trace,"Ia32eModeGuest                           %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, Ia32eModeGuest                 ));
   396      VMM_LOG(mask_anonymous, level_trace,"EntryToSmm                               %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, EntryToSmm                     ));
   397      VMM_LOG(mask_anonymous, level_trace,"TearDownSmmMonitor                       %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, TearDownSmmMonitor             ));
   398      VMM_LOG(mask_anonymous, level_trace,"LoadSysEnterMsrs                         %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadSysEnterMsrs               ));
   399      VMM_LOG(mask_anonymous, level_trace,"LoadPat                                  %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadPat                        ));
   400      VMM_LOG(mask_anonymous, level_trace,"LoadEfer                                 %c\n",VMCS_FIXED_BIT_2_CHAR( vm_entry_ctrl, LoadEfer                       ));
   401  
   402      VMM_LOG(mask_anonymous, level_trace,"\n");
   403      VMM_LOG(mask_anonymous, level_trace,"Cr0 Bits                               Value\n");
   404      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   405      VMM_LOG(mask_anonymous, level_trace,"PE                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, PE ));
   406      VMM_LOG(mask_anonymous, level_trace,"MP                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, MP ));
   407      VMM_LOG(mask_anonymous, level_trace,"EM                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, EM ));
   408      VMM_LOG(mask_anonymous, level_trace,"TS                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, TS ));
   409      VMM_LOG(mask_anonymous, level_trace,"ET                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, ET ));
   410      VMM_LOG(mask_anonymous, level_trace,"NE                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, NE ));
   411      VMM_LOG(mask_anonymous, level_trace,"WP                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, WP ));
   412      VMM_LOG(mask_anonymous, level_trace,"AM                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, AM ));
   413      VMM_LOG(mask_anonymous, level_trace,"NW                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, NW ));
   414      VMM_LOG(mask_anonymous, level_trace,"CD                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, CD ));
   415      VMM_LOG(mask_anonymous, level_trace,"PG                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr0, PG ));
   416  
   417      VMM_LOG(mask_anonymous, level_trace,"\n");
   418      VMM_LOG(mask_anonymous, level_trace,"Cr4 Bits                               Value\n");
   419      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   420      VMM_LOG(mask_anonymous, level_trace,"VME                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, VME        ));
   421      VMM_LOG(mask_anonymous, level_trace,"PVI                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, PVI        ));
   422      VMM_LOG(mask_anonymous, level_trace,"TSD                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, TSD        ));
   423      VMM_LOG(mask_anonymous, level_trace,"DE                                       %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, DE         ));
   424      VMM_LOG(mask_anonymous, level_trace,"PSE                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, PSE        ));
   425      VMM_LOG(mask_anonymous, level_trace,"PAE                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, PAE        ));
   426      VMM_LOG(mask_anonymous, level_trace,"MCE                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, MCE        ));
   427      VMM_LOG(mask_anonymous, level_trace,"PGE                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, PGE        ));
   428      VMM_LOG(mask_anonymous, level_trace,"PCE                                      %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, PCE        ));
   429      VMM_LOG(mask_anonymous, level_trace,"OSFXSR                                   %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, OSFXSR     ));
   430      VMM_LOG(mask_anonymous, level_trace,"OSXMMEXCPT                               %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, OSXMMEXCPT ));
   431      VMM_LOG(mask_anonymous, level_trace,"VMXE                                     %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, VMXE       ));
   432      VMM_LOG(mask_anonymous, level_trace,"SMXE                                     %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, SMXE       ));
   433      VMM_LOG(mask_anonymous, level_trace,"OSXSAVE                                  %c\n",VMCS_FIXED_BIT_2_CHAR( cr4, OSXSAVE    ));
   434  
   435      VMM_LOG(mask_anonymous, level_trace,"\n");
   436      VMM_LOG(mask_anonymous, level_trace,"EPT & VPID Capabilities                Value\n");
   437      VMM_LOG(mask_anonymous, level_trace,"(Valid only if EnableEPT or EnableVPID is not fixed 0)\n");
   438      VMM_LOG(mask_anonymous, level_trace,"=====================================  =====\n");
   439      VMM_LOG(mask_anonymous, level_trace,"X_only                                   %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, X_only                  ));
   440      VMM_LOG(mask_anonymous, level_trace,"W_only                                   %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, W_only                  ));
   441      VMM_LOG(mask_anonymous, level_trace,"W_and_X_only                             %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, W_and_X_only            ));
   442      VMM_LOG(mask_anonymous, level_trace,"GAW_21_bit                               %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, GAW_21_bit              ));
   443      VMM_LOG(mask_anonymous, level_trace,"GAW_30_bit                               %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, GAW_30_bit              ));
   444      VMM_LOG(mask_anonymous, level_trace,"GAW_39_bit                               %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, GAW_39_bit              ));
   445      VMM_LOG(mask_anonymous, level_trace,"GAW_48_bit                               %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, GAW_48_bit              ));
   446      VMM_LOG(mask_anonymous, level_trace,"GAW_57_bit                               %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, GAW_57_bit              ));
   447      VMM_LOG(mask_anonymous, level_trace,"UC                                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, UC                      ));
   448      VMM_LOG(mask_anonymous, level_trace,"WC                                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, WC                      ));
   449      VMM_LOG(mask_anonymous, level_trace,"WT                                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, WT                      ));
   450      VMM_LOG(mask_anonymous, level_trace,"WP                                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, WP                      ));
   451      VMM_LOG(mask_anonymous, level_trace,"WB                                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, WB                      ));
   452      VMM_LOG(mask_anonymous, level_trace,"SP_21_bit                                %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, SP_21_bit               ));
   453      VMM_LOG(mask_anonymous, level_trace,"SP_30_bit                                %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, SP_30_bit               ));
   454      VMM_LOG(mask_anonymous, level_trace,"SP_39_bit                                %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, SP_39_bit               ));
   455      VMM_LOG(mask_anonymous, level_trace,"SP_48_bit                                %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, SP_48_bit               ));
   456      VMM_LOG(mask_anonymous, level_trace,"InveptSupported                          %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InveptSupported         ));
   457      VMM_LOG(mask_anonymous, level_trace,"InveptIndividualAddress                  %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InveptIndividualAddress ));
   458      VMM_LOG(mask_anonymous, level_trace,"InveptContextWide                        %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InveptContextWide       ));
   459      VMM_LOG(mask_anonymous, level_trace,"InveptAllContexts                        %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InveptAllContexts       ));
   460      VMM_LOG(mask_anonymous, level_trace,"InvvpidSupported                         %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InvvpidSupported        ));
   461      VMM_LOG(mask_anonymous, level_trace,"InvvpidIndividualAddress                 %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InvvpidIndividualAddress));
   462      VMM_LOG(mask_anonymous, level_trace,"InvvpidContextWide                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InvvpidContextWide      ));
   463      VMM_LOG(mask_anonymous, level_trace,"InvvpidAllContexts                       %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InvvpidAllContexts      ));
   464      VMM_LOG(mask_anonymous, level_trace,"InvvpidAllContextsPreservingGlobals      %c\n",CAP_BIT_TO_CHAR( EptVpidCapabilities, InvvpidAllContextsPreservingGlobals));
   465  
   466      VMM_LOG(mask_anonymous, level_trace,"\n");
   467      VMM_LOG(mask_anonymous, level_trace,"---------------- End of Discovered VMX capabilities --------------\n");
   468      VMM_LOG(mask_anonymous, level_trace,"\n");
   469  }
   470  #endif //DEBUG
   471  
   472  
   473  //      interface functions
   474  
   475  void vmcs_hw_init( void )
   476  {
   477      if (g_init_done) {
   478  #ifdef JLMDEBUG1
   479          bprint("vmcs_hw_init returning\n");
   480  #endif
   481          return;
   482      }
   483      vmm_memset(&g_vmx_capabilities, 0, sizeof(g_vmx_capabilities));
   484      vmm_memset(&g_vmx_constraints, 0, sizeof(g_vmx_constraints));
   485      vmm_memset(&g_vmx_fixed, 0, sizeof(g_vmx_fixed));
   486      g_init_done = TRUE;
   487      fill_vmx_capabilities();
   488  }
   489  
   490  
   491  // Allocate VMCS region
   492  HVA vmcs_hw_allocate_region(HPA* hpa)
   493  {
   494      HVA             hva = 0;
   495      IA32_VMX_VMCS*  vmcs = 0;
   496  
   497  #ifdef JLMDEBUG1
   498      bprint("vmcs_hw_allocate_region\n");
   499  #endif
   500      VMM_ASSERT( hpa );
   501      // allocate the VMCS area
   502      // the area must be 4K page aligned and zeroed
   503      hva = (HVA)vmm_memory_alloc(VMCS_REGION_SIZE);
   504      if(hva == 0) {
   505  #ifdef JLMDEBUG
   506          bprint("vmm_memory_alloc(%llu) failed\n", VMCS_REGION_SIZE);
   507          UINT64 check= hw_read_msr(IA32_MSR_VMCS_REVISION_IDENTIFIER_INDEX);
   508          bprint("read MSR_VMCS_REVISION_IDENTIFIER: %llx\n", check);
   509          LOOP_FOREVER
   510  #endif
   511      }
   512      VMM_ASSERT(hva);
   513      if (!hmm_hva_to_hpa(hva, hpa)) {
   514          VMM_LOG(mask_anonymous, level_trace,
   515                  "%s:(%d):ASSERT: HVA to HPA conversion failed\n", 
   516                  __FUNCTION__, __LINE__);
   517          VMM_DEADLOOP();
   518      }
   519  #ifdef JLMDEBUG
   520      bprint("vmcs_hw_allocate_region after hmm_hva_to_hpa %llx\n", hva);
   521  #endif
   522      // check VMCS memory type
   523      VMM_ASSERT(hmm_does_memory_range_have_specified_memory_type(
   524                   *hpa, VMCS_REGION_SIZE, VMCS_MEMORY_TYPE ) == TRUE);
   525      vmcs = (IA32_VMX_VMCS*)hva;
   526      vmcs->RevisionIdentifier = VMCS_REVISION;
   527      // unmap VMCS region from the host memory
   528  #if 0  // unmap VMCS region from host
   529      if(!hmm_unmap_hpa(*hpa, ALIGN_FORWARD(VMCS_REGION_SIZE, PAGE_4KB_SIZE), FALSE)) {
   530          VMM_LOG(mask_anonymous, level_trace,"ERROR: failed to unmap VMCS\n");
   531          VMM_DEADLOOP();
   532      }
   533  #endif
   534      return hva;
   535  }
   536  
   537  
   538  // allocate vmxon regions for all processors at once
   539  // must be called once only on BSP before vmx_on on any APs.
   540  BOOLEAN vmcs_hw_allocate_vmxon_regions(UINT16 max_host_cpus)
   541  {
   542      HVA     vmxon_region_hva = 0;
   543      HPA     vmxon_region_hpa = 0;
   544      UINT16  cpu_idx = 0;
   545  
   546      VMM_ASSERT( max_host_cpus );
   547      for(cpu_idx = 0; cpu_idx < max_host_cpus; cpu_idx ++ ) {
   548          vmxon_region_hva = vmcs_hw_allocate_region(&vmxon_region_hpa);
   549          host_cpu_set_vmxon_region(vmxon_region_hva, vmxon_region_hpa, cpu_idx);
   550      }
   551      return TRUE;
   552  }
   553  
   554  
   555  //
   556  // get constraints
   557  //
   558  const VMCS_HW_CONSTRAINTS* vmcs_hw_get_vmx_constraints( void )
   559  {
   560      if (! g_init_done) {
   561          vmcs_hw_init();
   562      }
   563      return &g_vmx_constraints;
   564  }
   565  
   566  
   567  // Check that current CPU is VMX-capable
   568  BOOLEAN vmcs_hw_is_cpu_vmx_capable( void )
   569  {
   570      CPUID_INFO_STRUCT cpuid_info;
   571      IA32_MSR_OPT_IN   opt_in;
   572      BOOLEAN           ok = FALSE;
   573  #ifdef JLMDEBUG1
   574      bprint("vmcs_hw_is_cpu_vmx_capable\n");
   575  #endif
   576  
   577      // 1. CPUID[EAX=1] should have VMX feature == 1
   578      // 2. OPT_IN (FEATURE_CONTROL) MSR should have
   579      //     either EnableVmxonOutsideSmx == 1 or
   580      //     Lock == 0
   581      cpuid( &cpuid_info, 1 );
   582      if ((CPUID_VALUE_ECX( cpuid_info ) & IA32_CPUID_ECX_VMX) == 0) {
   583          VMM_LOG(mask_anonymous, level_trace,"ASSERT: CPUID[EAX=1] indicates that Host CPU #%d does not support VMX!\n",
   584                   hw_cpu_id());
   585          return FALSE;
   586      }
   587      opt_in.Uint64 = hw_read_msr( IA32_MSR_OPT_IN_INDEX );
   588      ok = ((opt_in.Bits.EnableVmxonOutsideSmx == 1) || (opt_in.Bits.Lock == 0));
   589      VMM_DEBUG_CODE({
   590          if (!ok) {
   591              VMM_LOG(mask_anonymous, level_trace,"ASSERT: OPT_IN (FEATURE_CONTROL) MSR indicates that somebody locked-out VMX on Host CPU #%d\n",
   592                       hw_cpu_id());
   593          }
   594      })
   595      return ok;
   596  }
   597  
   598  
   599  // Enable VT on the current CPU
   600  void vmcs_hw_vmx_on( void )
   601  {
   602      IA32_MSR_OPT_IN   opt_in;
   603      EM64T_CR4         cr4;
   604      HVA               vmxon_region_hva = 0;
   605      HPA               vmxon_region_hpa = 0;
   606      int               vmx_ret= 0;
   607  
   608  #ifdef JLMDEBUG
   609     bprint("vmcs_hw_vmx_on\n");
   610  #endif
   611  
   612      // Enable VMX in CR4
   613      cr4.Uint64 = hw_read_cr4();
   614      cr4.Bits.VMXE = 1;
   615      hw_write_cr4(cr4.Uint64);
   616      // Enable VMX outside SMM in OPT_IN (FEATURE_CONTROL) MSR and lock it
   617      opt_in.Uint64 = hw_read_msr(IA32_MSR_OPT_IN_INDEX);
   618      VMM_ASSERT( (opt_in.Bits.Lock == 0) || (opt_in.Bits.EnableVmxonOutsideSmx == 1) );
   619      if (opt_in.Bits.Lock == 0) {
   620          opt_in.Bits.EnableVmxonOutsideSmx = 1;
   621          opt_in.Bits.Lock = 1;
   622          hw_write_msr(IA32_MSR_OPT_IN_INDEX, opt_in.Uint64);
   623      }
   624      vmxon_region_hva = host_cpu_get_vmxon_region(&vmxon_region_hpa);
   625  #ifdef JLMDEBUG
   626      bprint("vmxon_hpa: %llx, vmxon_region_hva: %llx\n",
   627              vmxon_region_hpa,  vmxon_region_hva);
   628      // not that the region with address vmxon_region_hva
   629      // has been unmapped, so we cant print it.
   630  #endif
   631      if(!vmxon_region_hva || !vmxon_region_hpa) {
   632          VMM_LOG(mask_anonymous, level_trace,
   633                  "ASSERT: VMXON failed with getting vmxon_region address\n");
   634          VMM_DEADLOOP();
   635      }
   636      vmx_ret = vmx_on(&vmxon_region_hpa);
   637  #ifdef JLMDEBUG
   638      if(vmx_ret==0) {
   639          bprint("vmxon succeeded\n");
   640      }
   641      else {
   642          bprint("vmxon failed %d\n", vmx_ret);
   643          LOOP_FOREVER
   644      }
   645  #endif
   646      switch(vmx_ret) {
   647          case HW_VMX_SUCCESS:
   648              host_cpu_set_vmx_state( TRUE );
   649              break;
   650          case HW_VMX_FAILED_WITH_STATUS:
   651              VMM_LOG(mask_anonymous, level_trace,
   652                  "ASSERT: VMXON failed with HW_VMX_FAILED_WITH_STATUS error\n");
   653              VMM_DEADLOOP();
   654              VMM_BREAKPOINT();
   655          case HW_VMX_FAILED:
   656          default:
   657              VMM_LOG(mask_anonymous, level_trace,"ASSERT: VMXON failed with HW_VMX_FAILED error\n");
   658              VMM_DEADLOOP();
   659              VMM_BREAKPOINT();
   660      }
   661  }
   662  
   663  
   664  // Disable VT on the current CPU
   665  void vmcs_hw_vmx_off( void )
   666  {
   667      if (host_cpu_get_vmx_state() == FALSE) {
   668          return;
   669      }
   670      vmx_off();
   671      host_cpu_set_vmx_state( FALSE );
   672  }
   673