github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/dbg/vmx_trace.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 "vmx_trace.h"
    16  #include "trace.h"
    17  #include "common_libc.h"
    18  //#include "vmcs_object.h"
    19  #include "vmcs_api.h"
    20  #include "scheduler.h"
    21  #include "hw_utils.h"
    22  #include "vmm_dbg.h"
    23  #include "file_codes.h"
    24  
    25  #define __builtin_va_end(p)
    26  #define __builtin_stdarg_start(a,b)
    27  #define __builtin_va_arg(a,p) 0
    28  
    29  #define VMM_DEADLOOP()          VMM_DEADLOOP_LOG(VMX_TRACE_C)
    30  #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(VMX_TRACE_C, __condition)
    31  
    32  static VMM_TRACE_STATE vmm_trace_state = VMM_TRACE_DISABLED;
    33  
    34  BOOLEAN vmm_trace_init( UINT32 max_num_guests, UINT32 max_num_guest_cpus)
    35  {
    36      static BOOLEAN called = FALSE;
    37  
    38      if ( ! called) {
    39          called = trace_init(max_num_guests, max_num_guest_cpus);
    40      }
    41  
    42      return called;
    43  }
    44  
    45  void vmm_trace_state_set(VMM_TRACE_STATE state)
    46  {
    47      switch (state) {
    48          case VMM_TRACE_DISABLED:
    49          case VMM_TRACE_ENABLED_RECYCLED:
    50          case VMM_TRACE_ENABLED_NON_RECYCLED:
    51              trace_set_recyclable(VMM_TRACE_ENABLED_RECYCLED == state);
    52              vmm_trace_state = state;
    53              break;
    54          default:
    55              break;
    56      }
    57  }
    58  
    59  
    60  static size_t vmm_trace_print_string( const char *format,
    61                         va_list marker, char *string)
    62  {
    63      char formatted_string[MAX_STRING_LENGTH];
    64      size_t max_index, length;
    65  
    66      if (VMM_TRACE_DISABLED == vmm_trace_state) {
    67          return 0;
    68      }
    69  
    70      max_index = vmm_strlen(format);
    71      if (max_index >= MAX_STRING_LENGTH) {
    72          VMM_DEADLOOP();
    73      }
    74  
    75      vmm_strcpy_s(formatted_string, MAX_STRING_LENGTH, format);
    76      formatted_string[max_index] = '\0';
    77  
    78      length = vmm_vsprintf_s(string, MAX_STRING_LENGTH, formatted_string, marker);
    79      if (length > MAX_STRING_LENGTH) {
    80          VMM_DEADLOOP();
    81      }
    82      return length;
    83  }
    84  
    85  
    86  BOOLEAN vmm_trace_buffer(GUEST_CPU_HANDLE   guest_cpu, UINT8  buffer_index,
    87                   const char *format, ...)
    88  {
    89      va_list                    marker;
    90      TRACE_RECORD_DATA	       data;
    91      VMCS_OBJECT*	       vmcs_obj = 0;
    92      const VIRTUAL_CPU_ID       *virtual_cpu_id = 0;
    93      GUEST_ID                   guest_id = 0;
    94      CPU_ID                     gcpu_id = 0;
    95  
    96      if (VMM_TRACE_DISABLED == vmm_trace_state) {
    97          return FALSE;
    98      }
    99  
   100      if (guest_cpu == NULL) {
   101          VMM_LOG(mask_anonymous, level_trace,"%a %d: Invalid parameter(s): guest_cpu 0x%x\n",
   102              __FUNCTION__, __LINE__, guest_cpu);
   103          VMM_DEADLOOP();
   104      }
   105  
   106      vmm_memset( &data, 0, sizeof( data ));
   107  
   108      va_start(marker, format);
   109      vmm_trace_print_string(format, marker, data.string);
   110      va_end(marker);
   111  
   112      vmcs_obj = gcpu_get_vmcs(guest_cpu);
   113      virtual_cpu_id = guest_vcpu(guest_cpu);
   114  
   115      if(vmcs_obj != NULL) {
   116          data.exit_reason = vmcs_read(vmcs_obj, VMCS_EXIT_INFO_REASON);
   117          data.guest_eip   = vmcs_read(vmcs_obj, VMCS_GUEST_RIP);
   118      }
   119      data.tsc        = (buffer_index == (MAX_TRACE_BUFFERS - 1))? hw_rdtsc(): 0;
   120  
   121      if(virtual_cpu_id != NULL) {
   122          guest_id = virtual_cpu_id->guest_id;
   123          gcpu_id = virtual_cpu_id->guest_cpu_id;
   124      }
   125  
   126      return trace_add_record(guest_id, gcpu_id, buffer_index, &data);
   127  }
   128  
   129  
   130  BOOLEAN
   131  vmm_trace( GUEST_CPU_HANDLE  guest_cpu, const char       *format,
   132            ...)
   133  {
   134      va_list                 marker;
   135      TRACE_RECORD_DATA       data;
   136      VMCS_OBJECT*		    vmcs_obj = 0;
   137      const VIRTUAL_CPU_ID    *virtual_cpu_id = 0;
   138      GUEST_ID                guest_id = 0;
   139      CPU_ID                  gcpu_id = 0;
   140  
   141      if (VMM_TRACE_DISABLED == vmm_trace_state)
   142      {
   143          return FALSE;
   144      }
   145  
   146      if (guest_cpu == NULL) {
   147          VMM_LOG(mask_anonymous, level_trace,"%a %d: Invalid parameter(s): guest_cpu 0x%x\n",
   148              __FUNCTION__, __LINE__, guest_cpu);
   149          VMM_DEADLOOP();
   150      }
   151  
   152      vmm_memset( &data, 0, sizeof( data ));
   153  
   154      va_start(marker, format);
   155      vmm_trace_print_string(format, marker, data.string);
   156      va_end(marker);
   157  
   158      vmcs_obj = gcpu_get_vmcs(guest_cpu);
   159      virtual_cpu_id = guest_vcpu(guest_cpu);
   160  
   161      if(vmcs_obj != NULL) {
   162          data.exit_reason = vmcs_read(vmcs_obj, VMCS_EXIT_INFO_REASON);
   163          data.guest_eip   = vmcs_read(vmcs_obj, VMCS_GUEST_RIP);
   164          data.tsc         = 0;
   165  //        data.tsc         = hw_rdtsc();
   166      }
   167  
   168      if(virtual_cpu_id != NULL) {
   169          guest_id = virtual_cpu_id->guest_id;
   170          gcpu_id = virtual_cpu_id->guest_cpu_id;
   171      }
   172      return trace_add_record(guest_id, gcpu_id, 0, &data);
   173  }
   174  
   175  
   176  BOOLEAN
   177  vmm_trace_print_all(UINT32 guest_num, char *guest_names[])
   178  {
   179      TRACE_RECORD_DATA record_data;
   180      UINT32 vm_index = 0, cpu_index = 0, buffer_index = 0, record_index = 0;
   181      int cnt = 0;
   182  
   183  
   184      if (VMM_TRACE_DISABLED == vmm_trace_state) {
   185          return FALSE;
   186      }
   187      trace_lock();
   188  
   189      VMM_LOG(mask_anonymous, level_trace,"\nTrace Events\n");
   190  
   191      while (trace_remove_oldest_record(&vm_index, &cpu_index, &buffer_index, &record_index, &record_data)) {
   192          char *vm_name;
   193          char buffer[5];
   194  
   195          if (0 == cnt++ % 0x1F)
   196          {
   197              VMM_LOG(mask_anonymous, level_trace,
   198                  "Buf   Index    TSC           | VM CPU  Exit Guest       EIP    | Message\n"
   199                  "-----------------------------+---------------------------------+---------------------\n");
   200          }
   201  
   202  	(void)vm_name;
   203          if (vm_index < guest_num) {
   204              vm_name = guest_names[vm_index];
   205  
   206          }
   207          else {
   208              vmm_sprintf_s(buffer, sizeof(buffer), "%4d", vm_index);
   209              vm_name = buffer;
   210          }
   211  
   212          VMM_LOG(mask_anonymous, level_trace,"%2d %8d %016lx |%4s %1d  %4d  %018P | %s",
   213              buffer_index, record_index, record_data.tsc, vm_name, cpu_index,
   214              record_data.exit_reason, record_data.guest_eip, record_data.string);
   215  
   216  
   217      }
   218  
   219      trace_unlock();
   220      return TRUE;
   221  }
   222