github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/arch/pat_manager.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_defs.h>
    16  #include <vmm_dbg.h>
    17  #include <vmm_startup.h>
    18  #include <hw_utils.h>
    19  #include <guest_cpu.h>
    20  #include <em64t_defs.h>
    21  #include <scheduler.h>
    22  #include <lock.h>
    23  #include <vmm_phys_mem_types.h>
    24  #include <pat_manager.h>
    25  #include <host_memory_manager_api.h>
    26  #include <vmm_events_data.h>
    27  #include <event_mgr.h>
    28  #include <host_cpu.h>
    29  #include <flat_page_tables.h>
    30  #include "file_codes.h"
    31  #define VMM_DEADLOOP()          VMM_DEADLOOP_LOG(PAT_MANAGER_C)
    32  #define VMM_ASSERT(__condition) VMM_ASSERT_LOG(PAT_MANAGER_C, __condition)
    33  #ifdef JLMDEBUG
    34  #include "jlmdebug.h"
    35  #endif
    36  
    37  #pragma warning (disable : 4100) // enable non-referenced formal parameters
    38  
    39  #define PAT_MNGR_INVALID_PAT_MSR_VALUE (~((UINT64)0))
    40  #define PAT_MNGR_NUM_OF_ATTRUBUTE_FIELDS 8
    41  
    42  static VMM_PHYS_MEM_TYPE pat_mngr_get_memory_type(UINT64 pat_value, UINT32 index) {
    43      UINT64 memory_type = ((pat_value >> (index*8)) & 0xff);
    44      return (VMM_PHYS_MEM_TYPE)memory_type;
    45  }
    46  #ifdef INCLUDE_UNUSED_CODE
    47  static
    48  BOOLEAN pat_mngr_is_memory_type_valid(VMM_PHYS_MEM_TYPE mem_type) {
    49      switch(mem_type) {
    50      case VMM_PHYS_MEM_UNCACHABLE:
    51      case VMM_PHYS_MEM_WRITE_COMBINING:
    52      case VMM_PHYS_MEM_WRITE_THROUGH:
    53      case VMM_PHYS_MEM_WRITE_PROTECTED:
    54      case VMM_PHYS_MEM_WRITE_BACK:
    55      case VMM_PHYS_MEM_UNCACHED:
    56          return TRUE;
    57      default:
    58          return FALSE;
    59      }
    60  }
    61  #endif
    62  
    63  UINT32 pat_mngr_get_earliest_pat_index_for_mem_type(VMM_PHYS_MEM_TYPE mem_type, 
    64                                                      UINT64 pat_msr_value) {
    65      UINT32 i;
    66  
    67      if (pat_msr_value == PAT_MNGR_INVALID_PAT_MSR_VALUE) {
    68          return PAT_MNGR_INVALID_PAT_INDEX;
    69      }
    70      for (i = 0; i < PAT_MNGR_NUM_OF_ATTRUBUTE_FIELDS; i++) {
    71          if (pat_mngr_get_memory_type(pat_msr_value, i) == mem_type) {
    72              return i;
    73          }
    74      }
    75      return PAT_MNGR_INVALID_PAT_INDEX;
    76  }
    77  
    78  UINT32 pat_mngr_retrieve_current_earliest_pat_index_for_mem_type(VMM_PHYS_MEM_TYPE mem_type) {
    79      UINT64 pat_msr_value = hw_read_msr(IA32_MSR_PAT);
    80      UINT32 result = 0;
    81  
    82      // assume that PAT MSR not used if its value is ZERO
    83      // then use compatibility setttings.
    84      if(pat_msr_value == 0){
    85          switch(mem_type) {
    86              case VMM_PHYS_MEM_WRITE_BACK:
    87                  result = 0; // see IA32 SDM, table 11-11/12 
    88                  break;
    89                  
    90              case VMM_PHYS_MEM_UNCACHABLE:
    91                  result = 3; // see IA32 SDM, table 11-11/12 
    92                  break;
    93  
    94              default:
    95                  result = PAT_MNGR_INVALID_PAT_INDEX;
    96                  VMM_LOG(mask_uvmm, level_error,
    97                          "CPU%d: %s: Error: mem type(%d) currently not supported\n",
    98                          hw_cpu_id(), __FUNCTION__, mem_type);
    99                  VMM_DEBUG_CODE(VMM_DEADLOOP();)
   100                  break; 
   101          }
   102      }
   103      else{
   104          result = pat_mngr_get_earliest_pat_index_for_mem_type(mem_type, pat_msr_value);
   105      }
   106      return result;
   107  }
   108  
   109  
   110  #ifdef INCLUDE_UNUSED_CODE
   111  VMM_PHYS_MEM_TYPE pat_mngr_retrieve_current_pat_mem_type(UINT32 pat_index) {
   112      UINT64 pat_msr_value = hw_read_msr(IA32_MSR_PAT);
   113      if (pat_index >= PAT_MNGR_NUM_OF_ATTRUBUTE_FIELDS) {
   114          VMM_ASSERT(0);
   115          return VMM_PHYS_MEM_UNDEFINED;
   116      }
   117      return pat_mngr_get_memory_type(pat_msr_value, pat_index);
   118  }
   119  #endif
   120  
   121  #ifdef ENABLE_VTLB
   122  BOOLEAN pat_mngr_get_pat_information(GUEST_CPU_HANDLE gcpu,
   123                       UINT64* guest_pat, UINT64* actual_pat) {
   124      VMCS_OBJECT* vmcs = gcpu_get_vmcs(gcpu);
   125      *guest_pat = gcpu_get_msr_reg(gcpu,IA32_VMM_MSR_PAT);
   126      *actual_pat = vmcs_read(vmcs, VMCS_HOST_PAT);
   127      return TRUE;
   128  }
   129  #endif