github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/startup/copy_input_structs.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 "vmm_bootstrap_utils.h"
    16  #include "libc.h"
    17  #include "heap.h"
    18  #include "vmm_dbg.h"
    19  #include "vmm_startup.h"
    20  #include "file_codes.h"
    21  #ifdef JLMDEBUG
    22  #include "jlmdebug.h"
    23  #endif
    24  
    25  #ifndef VMM_DEADLOOP
    26  #define VMM_DEADLOOP()          VMM_DEADLOOP_LOG(COPY_INPUT_STRUCTS_C)
    27  #endif
    28  
    29  #ifndef VMM_ASSERT
    30  #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(COPY_INPUT_STRUCTS_C, __condition)
    31  #endif
    32  
    33  
    34  // Copy input params into heap before changing host virtual memory mapping
    35  // Required in order to avoid input parameters disrupting
    36  INLINE void vmm_copy_gcpu_startup_state(VMM_GUEST_CPU_STARTUP_STATE* state_to, 
    37                                   const VMM_GUEST_CPU_STARTUP_STATE* state_from) {
    38      vmm_memcpy(state_to, state_from, state_from->size_of_this_struct);
    39  }
    40  
    41  INLINE void vmm_copy_guest_device(VMM_GUEST_DEVICE* guest_device_to, 
    42                                    const VMM_GUEST_DEVICE* guest_device_from) {
    43      vmm_memcpy(guest_device_to, guest_device_from, 
    44                 guest_device_from->size_of_this_struct);
    45  }
    46  
    47  
    48  static BOOLEAN vmm_copy_guest_startup(VMM_GUEST_STARTUP* guest_startup_to, 
    49                              const VMM_GUEST_STARTUP* guest_startup_from) {
    50      UINT32 size_of_array = 0;
    51      UINT32 i;
    52      void* array;
    53      VMM_GUEST_CPU_STARTUP_STATE* curr_state_to;
    54      const VMM_GUEST_CPU_STARTUP_STATE* curr_state_from;
    55      VMM_GUEST_DEVICE* curr_device_to;
    56      const VMM_GUEST_DEVICE* curr_device_from;
    57  
    58      // Copy the structure (one to one)
    59      vmm_memcpy(guest_startup_to, guest_startup_from, guest_startup_from->size_of_this_struct);
    60  
    61      // Create copy of VMM_GUEST_CPU_STARTUP_STATE array
    62      for (i = 0; i < guest_startup_from->cpu_states_count; i++) {
    63          UINT64 addr_of_cpu_state = guest_startup_from->cpu_states_array + size_of_array;
    64          const VMM_GUEST_CPU_STARTUP_STATE* state = (const VMM_GUEST_CPU_STARTUP_STATE*)addr_of_cpu_state;
    65  
    66          size_of_array += state->size_of_this_struct;
    67      }
    68  
    69      guest_startup_to->cpu_states_array = 0;
    70      if (size_of_array > 0) {
    71          array = vmm_memory_alloc(size_of_array);
    72          if (array == NULL) {
    73              return FALSE;
    74          }
    75          guest_startup_to->cpu_states_array = (UINT64)array;
    76  
    77          curr_state_from = (const VMM_GUEST_CPU_STARTUP_STATE*)guest_startup_from->cpu_states_array;
    78          curr_state_to = (VMM_GUEST_CPU_STARTUP_STATE*)array;
    79          for (i = 0; i < guest_startup_from->cpu_states_count; i++) {
    80              vmm_copy_gcpu_startup_state(curr_state_to, curr_state_from);
    81              curr_state_from = (const VMM_GUEST_CPU_STARTUP_STATE*)((UINT64)curr_state_from + curr_state_from->size_of_this_struct);
    82              curr_state_to = (VMM_GUEST_CPU_STARTUP_STATE*)((UINT64)curr_state_to + curr_state_to->size_of_this_struct);
    83          }
    84      }
    85  
    86      // Create copy of VMM_GUEST_DEVICE array
    87      size_of_array = 0;
    88      for (i = 0; i < guest_startup_from->devices_count; i++) {
    89          UINT64 addr_of_device_struct = guest_startup_from->devices_array + size_of_array;
    90          const VMM_GUEST_DEVICE* device = (const VMM_GUEST_DEVICE*)addr_of_device_struct;
    91  
    92          size_of_array += device->size_of_this_struct;
    93      }
    94  
    95      guest_startup_to->devices_array = 0;
    96  
    97      if (size_of_array > 0) {
    98          array = vmm_memory_alloc(size_of_array);
    99          if (array == NULL) {
   100              return FALSE;
   101          }
   102          guest_startup_to->devices_array = (UINT64)array;
   103  
   104          curr_device_from = (const VMM_GUEST_DEVICE*)guest_startup_from->devices_array;
   105          curr_device_to = (VMM_GUEST_DEVICE*)array;
   106          for (i = 0; i < guest_startup_from->devices_count; i++) {
   107              vmm_copy_guest_device(curr_device_to, curr_device_from);
   108              curr_device_from = (const VMM_GUEST_DEVICE*)((UINT64)curr_device_from + curr_device_from->size_of_this_struct);
   109              curr_device_to = (VMM_GUEST_DEVICE*)((UINT64)curr_device_to + curr_device_to->size_of_this_struct);
   110          }
   111      }
   112  
   113      // For SOS copy image into heap
   114      if (guest_startup_from->image_size != 0) {
   115          void* image_heap_addr;
   116  
   117          VMM_ASSERT(guest_startup_from->image_address != 0);
   118          image_heap_addr = vmm_memory_alloc(guest_startup_from->image_size);
   119          if (image_heap_addr == NULL) {
   120              return FALSE;
   121          }
   122  
   123          vmm_memcpy(image_heap_addr, (void*)(guest_startup_from->image_address), guest_startup_from->image_size);
   124          guest_startup_to->image_address = (UINT64)image_heap_addr;
   125      }
   126  
   127      return TRUE;
   128  }
   129  
   130  
   131  static const VMM_GUEST_STARTUP* vmm_create_guest_startup_copy(const VMM_GUEST_STARTUP* guest_startup_stack) {
   132      VMM_GUEST_STARTUP* guest_startup_heap = NULL;
   133  
   134      // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   135      VMM_ASSERT(guest_startup_stack->size_of_this_struct >= sizeof(VMM_GUEST_STARTUP));
   136      guest_startup_heap = (VMM_GUEST_STARTUP*)vmm_memory_alloc(guest_startup_stack->size_of_this_struct);
   137      if (guest_startup_heap == NULL) {
   138          return NULL;
   139      }
   140      if (!vmm_copy_guest_startup(guest_startup_heap, guest_startup_stack)) {
   141          return NULL;
   142      }
   143      return (const VMM_GUEST_STARTUP*)guest_startup_heap;
   144  }
   145  
   146  
   147  static void vmm_destroy_guest_startup_struct(const VMM_GUEST_STARTUP* guest_startup) {
   148  
   149      if (guest_startup == NULL) {
   150          return;
   151      }
   152  
   153      // For SOS: if the image is in heap, destroy it
   154      if (guest_startup->image_size != 0) {
   155  
   156          // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   157          VMM_ASSERT(guest_startup->image_address != 0);
   158          vmm_memory_free((void*)guest_startup->image_address);
   159      }
   160  
   161      // Destory all devices
   162      if (guest_startup->devices_array != 0) {
   163          vmm_memory_free((void*)guest_startup->devices_array);
   164      }
   165  
   166      // Destory all cpu state structs
   167      if (guest_startup->cpu_states_array != 0) {
   168          vmm_memory_free((void*)guest_startup->cpu_states_array);
   169      }
   170  }
   171  
   172  const VMM_STARTUP_STRUCT* vmm_create_startup_struct_copy(
   173          const VMM_STARTUP_STRUCT* startup_struct_stack) {
   174      VMM_STARTUP_STRUCT* startup_struct_heap = NULL;
   175      const VMM_GUEST_STARTUP* guest_startup_heap = NULL;
   176      void* secondary_guests_array;
   177      UINT32 size_of_array = 0;
   178      UINT32 i;
   179  
   180      if (startup_struct_stack == NULL) {
   181          return NULL;
   182      }
   183  
   184      // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   185      // Copy all the fields from the struct
   186      VMM_ASSERT(startup_struct_stack->size_of_this_struct >= sizeof(VMM_STARTUP_STRUCT));
   187      // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   188      VMM_ASSERT(ALIGN_BACKWARD((UINT64)startup_struct_stack, VMM_STARTUP_STRUCT_ALIGNMENT) == (UINT64)startup_struct_stack);
   189      startup_struct_heap = (VMM_STARTUP_STRUCT*)
   190                 vmm_memory_alloc(startup_struct_stack->size_of_this_struct);
   191      if (startup_struct_heap == NULL) {
   192          return NULL;
   193      }
   194      // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   195      VMM_ASSERT(ALIGN_BACKWARD((UINT64)startup_struct_heap, VMM_STARTUP_STRUCT_ALIGNMENT) == (UINT64)startup_struct_heap);
   196      vmm_memcpy(startup_struct_heap, startup_struct_stack, startup_struct_stack->size_of_this_struct);
   197  
   198      // Create copy of guest startup struct
   199      if (startup_struct_stack->primary_guest_startup_state != 0) {
   200          // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   201          VMM_ASSERT(ALIGN_BACKWARD(startup_struct_stack->primary_guest_startup_state, VMM_GUEST_STARTUP_ALIGNMENT) == startup_struct_stack->primary_guest_startup_state);
   202          guest_startup_heap = vmm_create_guest_startup_copy(
   203                   (const VMM_GUEST_STARTUP*)startup_struct_stack->primary_guest_startup_state);
   204          if (guest_startup_heap == NULL) {
   205              return NULL;
   206          }
   207          // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   208          VMM_ASSERT(ALIGN_BACKWARD((UINT64)guest_startup_heap, VMM_GUEST_STARTUP_ALIGNMENT) == (UINT64)guest_startup_heap);
   209          startup_struct_heap->primary_guest_startup_state = (UINT64)guest_startup_heap;
   210      }
   211  
   212      // Create copies of SOSes start up struct
   213      if (startup_struct_stack->number_of_secondary_guests > 0) {
   214          const VMM_GUEST_STARTUP* curr_guest_struct = NULL;
   215          VMM_GUEST_STARTUP* curr_guest_struct_heap = NULL;
   216  
   217          for (i = 0; i < startup_struct_stack->number_of_secondary_guests; i++) {
   218              UINT64 addr_of_guest_struct = 
   219                     startup_struct_stack->secondary_guests_startup_state_array + size_of_array;
   220              curr_guest_struct = (const VMM_GUEST_STARTUP*)addr_of_guest_struct;
   221              // BEFORE_VMLAUNCH. Failure check can be included in POSTLAUNCH.
   222              VMM_ASSERT(ALIGN_BACKWARD(addr_of_guest_struct, VMM_GUEST_STARTUP_ALIGNMENT) == addr_of_guest_struct);
   223              size_of_array += curr_guest_struct->size_of_this_struct;
   224          }
   225  
   226          secondary_guests_array = vmm_memory_alloc(size_of_array);
   227          if (secondary_guests_array == NULL) {
   228              return NULL;
   229          }
   230          startup_struct_heap->secondary_guests_startup_state_array = (UINT64)secondary_guests_array;
   231          curr_guest_struct = (const VMM_GUEST_STARTUP*)startup_struct_stack->secondary_guests_startup_state_array;
   232          curr_guest_struct_heap = (VMM_GUEST_STARTUP*)secondary_guests_array;
   233  
   234          for (i = 0; i < startup_struct_stack->number_of_secondary_guests; i++) {
   235              if (!vmm_copy_guest_startup(curr_guest_struct_heap, curr_guest_struct)) {
   236                  return NULL;
   237              }
   238  
   239              curr_guest_struct = (const VMM_GUEST_STARTUP*)
   240                      ((UINT64)curr_guest_struct + curr_guest_struct->size_of_this_struct);
   241              curr_guest_struct_heap = (VMM_GUEST_STARTUP*)
   242                      ((UINT64)curr_guest_struct_heap + curr_guest_struct_heap->size_of_this_struct);
   243          }
   244      }
   245  
   246      return (const VMM_STARTUP_STRUCT*)startup_struct_heap;
   247  
   248  }
   249  
   250  void vmm_destroy_startup_struct(const VMM_STARTUP_STRUCT* startup_struct) {
   251      UINT32 i;
   252  
   253      if (startup_struct == NULL) {
   254          return;
   255      }
   256  
   257      // Destroy SOSes guest structs
   258      if (startup_struct->number_of_secondary_guests > 0) {
   259          const VMM_GUEST_STARTUP* curr_guest_struct = (const VMM_GUEST_STARTUP*)startup_struct->secondary_guests_startup_state_array;
   260  
   261          for (i = 0; i < startup_struct->number_of_secondary_guests; i++) {
   262              vmm_destroy_guest_startup_struct(curr_guest_struct);
   263              curr_guest_struct = (const VMM_GUEST_STARTUP*)((UINT64)curr_guest_struct + curr_guest_struct->size_of_this_struct);
   264          }
   265          vmm_memory_free((void*)startup_struct->secondary_guests_startup_state_array);
   266      }
   267  
   268      // Destroy primary guest struct
   269      if (startup_struct->primary_guest_startup_state != 0) {
   270          vmm_destroy_guest_startup_struct((const VMM_GUEST_STARTUP*)startup_struct->primary_guest_startup_state);
   271          vmm_memory_free((void*)startup_struct->primary_guest_startup_state);
   272      }
   273  
   274      // Destory struct itself
   275      vmm_memory_free((void*)startup_struct);
   276  }
   277  
   278  const VMM_APPLICATION_PARAMS_STRUCT* vmm_create_application_params_struct_copy(
   279                  const VMM_APPLICATION_PARAMS_STRUCT* application_params_stack) {
   280      VMM_APPLICATION_PARAMS_STRUCT* application_params_heap;
   281  
   282      if (application_params_stack == NULL) {
   283          return NULL;
   284      }
   285  
   286      application_params_heap = (VMM_APPLICATION_PARAMS_STRUCT*)
   287                  vmm_memory_alloc(application_params_stack->size_of_this_struct);
   288      if (application_params_heap == NULL) {
   289          return NULL;
   290      }
   291      vmm_memcpy(application_params_heap, application_params_stack, 
   292                 application_params_stack->size_of_this_struct);
   293      return (VMM_APPLICATION_PARAMS_STRUCT*)application_params_heap;
   294  }
   295  
   296  void vmm_destroy_application_params_struct(const VMM_APPLICATION_PARAMS_STRUCT* application_params_struct) {
   297      if (application_params_struct == NULL) {
   298          return;
   299      }
   300      vmm_memory_free((void*)application_params_struct);
   301  }
   302  
   303  //-------------------------------- debug print ------------------------------
   304  
   305  #define PRINT_STARTUP_FIELD8( tabs, root, name )  \
   306              VMM_LOG(mask_anonymous, level_trace,"%s%-42s = 0x%02X\n", tabs, #name, root->name )
   307  #define PRINT_STARTUP_FIELD16( tabs, root, name )  \
   308              VMM_LOG(mask_anonymous, level_trace,"%s%-42s = 0x%04X\n", tabs, #name, root->name )
   309  #define PRINT_STARTUP_FIELD32( tabs, root, name )  \
   310              VMM_LOG(mask_anonymous, level_trace,"%s%-42s = 0x%08X\n", tabs, #name, root->name )
   311  #define PRINT_STARTUP_FIELD64( tabs, root, name )  \
   312              VMM_LOG(mask_anonymous, level_trace,"%s%-42s = 0x%016lX\n", tabs, #name, root->name )
   313  #define PRINT_STARTUP_FIELD128( tabs, root, name )   \
   314              VMM_LOG(mask_anonymous, level_trace,"%s%-42s = 0x%016lX%016lX\n",     \
   315                         tabs,                         \
   316                         #name,                        \
   317                         ((UINT64 *)&(root->name))[1], \
   318                         ((UINT64 *)&(root->name))[0])
   319  
   320  #ifdef DEBUG
   321  #pragma warning(disable : 4100 4189)
   322  static
   323  void print_guest_device_struct(const VMM_GUEST_DEVICE* startup_struct,
   324                                      UINT32 dev_idx )
   325  {
   326      const char* prefix = "    .";
   327  
   328      VMM_LOG(mask_anonymous, level_trace,"\n    ----------------- VMM_GUEST_DEVICE ----------------------\n\n");
   329  
   330      VMM_LOG(mask_anonymous, level_trace,"     =========> Guest device #%d\n", dev_idx );
   331  
   332      if (startup_struct == NULL) {
   333          VMM_LOG(mask_anonymous, level_trace,"    VMM_GUEST_DEVICE is NULL\n");
   334          goto end;
   335      }
   336  
   337      PRINT_STARTUP_FIELD16( prefix, startup_struct, size_of_this_struct );
   338      PRINT_STARTUP_FIELD16( prefix, startup_struct, version_of_this_struct );
   339  
   340      PRINT_STARTUP_FIELD16( prefix, startup_struct, real_vendor_id );
   341      PRINT_STARTUP_FIELD16( prefix, startup_struct, real_device_id );
   342  
   343      PRINT_STARTUP_FIELD16( prefix, startup_struct, virtual_vendor_id );
   344      PRINT_STARTUP_FIELD16( prefix, startup_struct, virtual_device_id );
   345  
   346  end:
   347      VMM_LOG(mask_anonymous, level_trace,"\n    ----------------- END of VMM_GUEST_DEVICE ---------------\n\n");
   348  }
   349  #pragma warning(default : 4100 4189)
   350  
   351  //pragma is needed because in "release" VMM_LOG translates to nothing
   352  //and parameters are not used
   353  #pragma warning(disable : 4100 4189)
   354  static
   355  void print_guest_cpu_startup_struct(const VMM_GUEST_CPU_STARTUP_STATE* startup_struct,
   356                                      UINT32 gcpu_idx )
   357  {
   358      const char* prefix = "    .";
   359  
   360      VMM_LOG(mask_anonymous, level_trace,"\n    ----------------- VMM_GUEST_CPU_STARTUP_STATE ----------------------\n\n");
   361  
   362      VMM_LOG(mask_anonymous, level_trace,"     =========> Guest CPU #%d %s\n", gcpu_idx,
   363                                      (gcpu_idx == 0) ? "(BSP)" : "" );
   364  
   365      if (startup_struct == NULL) {
   366          VMM_LOG(mask_anonymous, level_trace,"    VMM_GUEST_CPU_STARTUP_STATE is NULL\n");
   367          goto end;
   368      }
   369  
   370      PRINT_STARTUP_FIELD16( prefix, startup_struct, size_of_this_struct );
   371      PRINT_STARTUP_FIELD16( prefix, startup_struct, version_of_this_struct );
   372  
   373      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RAX] );
   374      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RBX] );
   375      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RCX] );
   376      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RDX] );
   377      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RDI] );
   378      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RSI] );
   379      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RBP] );
   380      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RSP] );
   381      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R8]  );
   382      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R9]  );
   383      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R10] );
   384      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R11] );
   385      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R12] );
   386      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R13] );
   387      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R14] );
   388      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_R15] );
   389      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RIP] );
   390      PRINT_STARTUP_FIELD64( prefix, startup_struct, gp.reg[IA32_REG_RFLAGS] );
   391  
   392      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM0] );
   393      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM1] );
   394      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM2] );
   395      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM3] );
   396      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM4] );
   397      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM5] );
   398      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM6] );
   399      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM7] );
   400      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM8] );
   401      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM9] );
   402      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM10]);
   403      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM11]);
   404      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM12]);
   405      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM13]);
   406      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM14]);
   407      PRINT_STARTUP_FIELD128( prefix, startup_struct, xmm.reg[IA32_REG_XMM15]);
   408  
   409      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_CS].base );
   410      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_CS].limit );
   411      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_CS].attributes );
   412      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_CS].selector );
   413  
   414      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_DS].base );
   415      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_DS].limit );
   416      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_DS].attributes );
   417      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_DS].selector );
   418  
   419      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_SS].base );
   420      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_SS].limit );
   421      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_SS].attributes );
   422      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_SS].selector );
   423  
   424      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_ES].base );
   425      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_ES].limit );
   426      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_ES].attributes );
   427      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_ES].selector );
   428  
   429      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_FS].base );
   430      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_FS].limit );
   431      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_FS].attributes );
   432      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_FS].selector );
   433  
   434      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_GS].base );
   435      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_GS].limit );
   436      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_GS].attributes );
   437      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_GS].selector );
   438  
   439      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_LDTR].base );
   440      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_LDTR].limit );
   441      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_LDTR].attributes );
   442      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_LDTR].selector );
   443  
   444      PRINT_STARTUP_FIELD64( prefix, startup_struct, seg.segment[IA32_SEG_TR].base );
   445      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_TR].limit );
   446      PRINT_STARTUP_FIELD32( prefix, startup_struct, seg.segment[IA32_SEG_TR].attributes );
   447      PRINT_STARTUP_FIELD16( prefix, startup_struct, seg.segment[IA32_SEG_TR].selector );
   448  
   449      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.cr[IA32_CTRL_CR0]);
   450      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.cr[IA32_CTRL_CR2]);
   451      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.cr[IA32_CTRL_CR3]);
   452      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.cr[IA32_CTRL_CR4]);
   453      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.cr[IA32_CTRL_CR8]);
   454  
   455      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.gdtr.base );
   456      PRINT_STARTUP_FIELD32( prefix, startup_struct, control.gdtr.limit );
   457  
   458      PRINT_STARTUP_FIELD64( prefix, startup_struct, control.idtr.base );
   459      PRINT_STARTUP_FIELD32( prefix, startup_struct, control.idtr.limit );
   460  
   461      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.msr_debugctl );
   462      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.msr_efer );
   463      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.msr_pat );
   464      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.msr_sysenter_esp );
   465      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.msr_sysenter_eip );
   466      PRINT_STARTUP_FIELD64( prefix, startup_struct, msr.pending_exceptions );
   467      PRINT_STARTUP_FIELD32( prefix, startup_struct, msr.msr_sysenter_cs );
   468      PRINT_STARTUP_FIELD32( prefix, startup_struct, msr.interruptibility_state );
   469      PRINT_STARTUP_FIELD32( prefix, startup_struct, msr.activity_state );
   470      PRINT_STARTUP_FIELD32( prefix, startup_struct, msr.smbase );
   471  
   472  end:
   473      VMM_LOG(mask_anonymous, level_trace,"\n    ----------------- END of VMM_GUEST_CPU_STARTUP_STATE ---------------\n\n");
   474  }
   475  
   476  #pragma warning(default : 4100 4189)
   477  
   478  //pragma is needed because in "release" VMM_LOG translates to nothing
   479  //and parameters are not used
   480  #pragma warning(disable : 4189)
   481  static
   482  void print_guest_startup_struct(const VMM_GUEST_STARTUP* startup_struct,
   483                                  UINT32 guest_idx ) // if -1 - primary
   484  {
   485      const char* prefix = "  .";
   486      const VMM_GUEST_CPU_STARTUP_STATE* gcpu;
   487      const VMM_GUEST_DEVICE*            dev;
   488      UINT32 i;
   489  
   490      VMM_LOG(mask_anonymous, level_trace,"\n  ----------------- VMM_GUEST_STARTUP ----------------------\n\n");
   491  
   492      if (guest_idx == (UINT32)-1) {
   493          VMM_LOG(mask_anonymous, level_trace,"   =========> The PRIMARY guest\n");
   494      }
   495      else {
   496          VMM_LOG(mask_anonymous, level_trace,"   =========> Secondary guest #%d\n", guest_idx );
   497      }
   498  
   499      if (startup_struct == NULL) {
   500          VMM_LOG(mask_anonymous, level_trace,"  VMM_GUEST_STARTUP is NULL\n");
   501          goto end;
   502      }
   503  
   504      PRINT_STARTUP_FIELD16( prefix, startup_struct, size_of_this_struct );
   505      PRINT_STARTUP_FIELD16( prefix, startup_struct, version_of_this_struct );
   506      PRINT_STARTUP_FIELD32( prefix, startup_struct, flags );
   507      PRINT_STARTUP_FIELD32( prefix, startup_struct, guest_magic_number );
   508      PRINT_STARTUP_FIELD32( prefix, startup_struct, cpu_affinity );
   509      PRINT_STARTUP_FIELD32( prefix, startup_struct, cpu_states_count );
   510      PRINT_STARTUP_FIELD32( prefix, startup_struct, devices_count );
   511      PRINT_STARTUP_FIELD32( prefix, startup_struct, image_size );
   512      PRINT_STARTUP_FIELD64( prefix, startup_struct, image_address );
   513      PRINT_STARTUP_FIELD32( prefix, startup_struct, physical_memory_size );
   514      PRINT_STARTUP_FIELD32( prefix, startup_struct, image_offset_in_guest_physical_memory );
   515      PRINT_STARTUP_FIELD64( prefix, startup_struct, cpu_states_array );
   516      PRINT_STARTUP_FIELD64( prefix, startup_struct, devices_array );
   517  
   518      gcpu = (const VMM_GUEST_CPU_STARTUP_STATE*)(startup_struct->cpu_states_array);
   519      for (i = 0; i < startup_struct->cpu_states_count; ++i) {
   520          print_guest_cpu_startup_struct( gcpu + i, i );
   521      }
   522  
   523      dev = (const VMM_GUEST_DEVICE*)(startup_struct->devices_array);
   524      for (i = 0; i < startup_struct->devices_count; ++i) {
   525          print_guest_device_struct( dev + i, i );
   526      }
   527  
   528  end:
   529      VMM_LOG(mask_anonymous, level_trace,"\n  ----------------- END of VMM_GUEST_STARTUP ---------------\n\n");
   530  }
   531  
   532  
   533  #pragma warning(default : 4189)
   534  
   535  //pragma is needed because in "release" VMM_LOG translates to nothing
   536  //and parameters are not used
   537  #pragma warning(disable : 4189)
   538  
   539  void print_startup_struct(const VMM_STARTUP_STRUCT* startup_struct)
   540  {
   541      const char* prefix = ".";
   542      UINT16  idx;
   543  
   544      VMM_LOG(mask_anonymous, level_trace,"\n----------------- VMM_STARTUP_STRUCT ----------------------\n\n");
   545      if (startup_struct == NULL) {
   546          VMM_LOG(mask_anonymous, level_trace,"VMM_STARTUP_STRUCT is NULL\n");
   547          goto end;
   548      }
   549  
   550      PRINT_STARTUP_FIELD16( prefix, startup_struct, size_of_this_struct );
   551      PRINT_STARTUP_FIELD16( prefix, startup_struct, version_of_this_struct );
   552      PRINT_STARTUP_FIELD16( prefix, startup_struct, number_of_processors_at_install_time );
   553      PRINT_STARTUP_FIELD16( prefix, startup_struct, number_of_processors_at_boot_time );
   554      PRINT_STARTUP_FIELD16( prefix, startup_struct, number_of_secondary_guests );
   555      PRINT_STARTUP_FIELD16( prefix, startup_struct, size_of_vmm_stack );
   556      PRINT_STARTUP_FIELD16( prefix, startup_struct, unsupported_vendor_id );
   557      PRINT_STARTUP_FIELD16( prefix, startup_struct, unsupported_device_id );
   558      PRINT_STARTUP_FIELD32( prefix, startup_struct, flags );
   559      PRINT_STARTUP_FIELD32( prefix, startup_struct, default_device_owner );
   560      PRINT_STARTUP_FIELD32( prefix, startup_struct, acpi_owner );
   561      PRINT_STARTUP_FIELD32( prefix, startup_struct, nmi_owner );
   562      PRINT_STARTUP_FIELD32( prefix, startup_struct, vmm_memory_layout[uvmm_image].total_size );
   563      PRINT_STARTUP_FIELD32( prefix, startup_struct, vmm_memory_layout[uvmm_image].image_size );
   564      PRINT_STARTUP_FIELD64( prefix, startup_struct, vmm_memory_layout[uvmm_image].base_address );
   565      PRINT_STARTUP_FIELD64( prefix, startup_struct, physical_memory_layout_E820 );
   566      PRINT_STARTUP_FIELD64( prefix, startup_struct, primary_guest_startup_state );
   567      PRINT_STARTUP_FIELD64( prefix, startup_struct, secondary_guests_startup_state_array );
   568      PRINT_STARTUP_FIELD8(  prefix, startup_struct, debug_params.verbosity );
   569      PRINT_STARTUP_FIELD64( prefix, startup_struct, debug_params.mask );
   570      PRINT_STARTUP_FIELD8(  prefix, startup_struct, debug_params.port.type );
   571      PRINT_STARTUP_FIELD8(  prefix, startup_struct, debug_params.port.virt_mode );
   572      PRINT_STARTUP_FIELD8(  prefix, startup_struct, debug_params.port.ident_type );
   573      PRINT_STARTUP_FIELD32( prefix, startup_struct, debug_params.port.ident.ident32 );
   574  
   575      print_guest_startup_struct( (const VMM_GUEST_STARTUP*)(startup_struct->primary_guest_startup_state ),
   576                                  (UINT32)-1);
   577  
   578      for (idx = 0; idx < startup_struct->number_of_secondary_guests; ++idx) {
   579          const VMM_GUEST_STARTUP* sec = (const VMM_GUEST_STARTUP*)(startup_struct->secondary_guests_startup_state_array );
   580          print_guest_startup_struct( sec + idx, idx );
   581      }
   582  
   583  end:
   584      VMM_LOG(mask_anonymous, level_trace,"\n----------------- END of VMM_STARTUP_STRUCT ---------------\n\n");
   585  }
   586  #pragma warning(default : 4189)
   587  #endif //DEBUG