void efer_msr_set_nxe(void) { IA32_EFER_S efer_reg; efer_reg.Uint64 = hw_read_msr(IA32_MSR_EFER); if (efer_reg.Bits.NXE == 0) { efer_reg.Bits.NXE = 1; hw_write_msr(IA32_MSR_EFER, efer_reg.Uint64); } }
/* * Setup minimal controls for Guest CPU */ static void gcpu_minimal_controls(guest_cpu_handle_t gcpu) { vmcs_object_t *vmcs = mon_gcpu_get_vmcs(gcpu); uint32_t idx; const vmcs_hw_constraints_t *vmx_constraints = mon_vmcs_hw_get_vmx_constraints(); MON_ASSERT(vmcs); init_minimal_controls(gcpu); gcpu_apply_all(gcpu); /* * Disable CR3 Target Values by setting the count to 0 * * * Disable CR3 Target Values by setting the count to 0 and all the values * to 0xFFFFFFFF */ mon_vmcs_write(vmcs, VMCS_CR3_TARGET_COUNT, 0); for (idx = 0; idx < vmx_constraints->number_of_cr3_target_values; ++idx) mon_vmcs_write(vmcs, (vmcs_field_t)VMCS_CR3_TARGET_VALUE(idx), UINT64_ALL_ONES); /* * Set additional required fields */ mon_vmcs_write(vmcs, VMCS_GUEST_WORKING_VMCS_PTR, UINT64_ALL_ONES); mon_vmcs_write(vmcs, VMCS_GUEST_SYSENTER_CS, hw_read_msr(IA32_MSR_SYSENTER_CS)); mon_vmcs_write(vmcs, VMCS_GUEST_SYSENTER_ESP, hw_read_msr(IA32_MSR_SYSENTER_ESP)); mon_vmcs_write(vmcs, VMCS_GUEST_SYSENTER_EIP, hw_read_msr(IA32_MSR_SYSENTER_EIP)); mon_vmcs_write(vmcs, VMCS_GUEST_IA32_PERF_GLOBAL_CTRL, hw_read_msr(IA32_MSR_PERF_GLOBAL_CTRL)); }
boolean_t mtrrs_abstraction_ap_initialize(void) { uint32_t msr_addr; uint32_t index; if (!mtrrs_cached_info.is_initialized) { MON_LOG(mask_anonymous, level_error, "ERROR: MTRRs Abstraction: Initializing AP before BSP\n"); goto failed; } if (mtrrs_cached_info.ia32_mtrrcap_reg.value != hw_read_msr(IA32_MTRRCAP_ADDR)) { MON_LOG(mask_anonymous, level_error, "ERROR: MTRRs Abstraction: IA32_MTRRCAP doesn't match\n"); goto failed; } if (mtrrs_cached_info.ia32_mtrr_def_type.value != hw_read_msr(IA32_MTRR_DEF_TYPE_ADDR)) { MON_LOG(mask_anonymous, level_error, "ERROR: MTRRs Abstraction: IA32_MTRR_DEF_TYPE doesn't match\n"); goto failed; } if (mtrrs_abstraction_are_fixed_regs_supported()) { if ((mtrrs_cached_info.ia32_mtrr_fix[0].value != hw_read_msr(IA32_MTRR_FIX64K_00000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[1].value != hw_read_msr(IA32_MTRR_FIX16K_80000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[2].value != hw_read_msr(IA32_MTRR_FIX16K_A0000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[3].value != hw_read_msr(IA32_MTRR_FIX4K_C0000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[4].value != hw_read_msr(IA32_MTRR_FIX4K_C8000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[5].value != hw_read_msr(IA32_MTRR_FIX4K_D0000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[6].value != hw_read_msr(IA32_MTRR_FIX4K_D8000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[7].value != hw_read_msr(IA32_MTRR_FIX4K_E0000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[8].value != hw_read_msr(IA32_MTRR_FIX4K_E8000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[9].value != hw_read_msr(IA32_MTRR_FIX4K_F0000_ADDR)) || (mtrrs_cached_info.ia32_mtrr_fix[10].value != hw_read_msr(IA32_MTRR_FIX4K_F8000_ADDR))) { MON_LOG(mask_anonymous, level_error, "ERROR: MTRRs Abstraction: One (or more)" " of the fixed range MTRRs doesn't match\n"); goto failed; } } for (msr_addr = IA32_MTRR_PHYSBASE0_ADDR, index = 0; index < mtrrs_abstraction_get_num_of_variable_range_regs(); msr_addr += 2, index++) { if (msr_addr > IA32_MTRR_MAX_PHYSMASK_ADDR) { MON_LOG(mask_mon, level_error, "AP: ERROR: MTRRs Abstraction: Variable MTRRs count > %d", MTRRS_ABS_NUM_OF_VAR_RANGE_MTRRS); MON_DEADLOOP(); } if ((mtrrs_cached_info.ia32_mtrr_var_phys_base[index].value != hw_read_msr(msr_addr)) || (mtrrs_cached_info.ia32_mtrr_var_phys_mask[index].value != hw_read_msr(msr_addr + 1))) { /* * MTRR MSR registers on the AP processors are not correctly * programmed by BIOS firmware. Just ignore this error, and * xmon programs EPT (Memory Type) based on the BSP’s MTRR values. */ MON_LOG(mask_anonymous, level_warning, "WARN: MTRRs Abstraction: One (or more)" " of the variable range MTRRs doesn't match\n"); } } return TRUE; failed: MON_ASSERT(0); return FALSE; }
/*---------------------------------------------------*/ boolean_t mtrrs_abstraction_bsp_initialize(void) { uint32_t msr_addr; uint32_t index; mon_memset(&mtrrs_cached_info, 0, sizeof(mtrrs_cached_info)); mtrrs_cached_info.ia32_mtrrcap_reg.value = hw_read_msr(IA32_MTRRCAP_ADDR); mtrrs_cached_info.ia32_mtrr_def_type.value = hw_read_msr(IA32_MTRR_DEF_TYPE_ADDR); if (mtrrs_abstraction_are_fixed_regs_supported()) { mtrrs_cached_info.ia32_mtrr_fix[0].value = hw_read_msr(IA32_MTRR_FIX64K_00000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[0].start_addr = 0x0; mtrrs_cached_info.ia32_mtrr_fix_range[0].end_addr = 0x7ffff; mtrrs_cached_info.ia32_mtrr_fix[1].value = hw_read_msr(IA32_MTRR_FIX16K_80000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[1].start_addr = 0x80000; mtrrs_cached_info.ia32_mtrr_fix_range[1].end_addr = 0x9ffff; mtrrs_cached_info.ia32_mtrr_fix[2].value = hw_read_msr(IA32_MTRR_FIX16K_A0000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[2].start_addr = 0xa0000; mtrrs_cached_info.ia32_mtrr_fix_range[2].end_addr = 0xbffff; mtrrs_cached_info.ia32_mtrr_fix[3].value = hw_read_msr(IA32_MTRR_FIX4K_C0000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[3].start_addr = 0xc0000; mtrrs_cached_info.ia32_mtrr_fix_range[3].end_addr = 0xc7fff; mtrrs_cached_info.ia32_mtrr_fix[4].value = hw_read_msr(IA32_MTRR_FIX4K_C8000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[4].start_addr = 0xc8000; mtrrs_cached_info.ia32_mtrr_fix_range[4].end_addr = 0xcffff; mtrrs_cached_info.ia32_mtrr_fix[5].value = hw_read_msr(IA32_MTRR_FIX4K_D0000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[5].start_addr = 0xd0000; mtrrs_cached_info.ia32_mtrr_fix_range[5].end_addr = 0xd7fff; mtrrs_cached_info.ia32_mtrr_fix[6].value = hw_read_msr(IA32_MTRR_FIX4K_D8000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[6].start_addr = 0xd8000; mtrrs_cached_info.ia32_mtrr_fix_range[6].end_addr = 0xdffff; mtrrs_cached_info.ia32_mtrr_fix[7].value = hw_read_msr(IA32_MTRR_FIX4K_E0000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[7].start_addr = 0xe0000; mtrrs_cached_info.ia32_mtrr_fix_range[7].end_addr = 0xe7fff; mtrrs_cached_info.ia32_mtrr_fix[8].value = hw_read_msr(IA32_MTRR_FIX4K_E8000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[8].start_addr = 0xe8000; mtrrs_cached_info.ia32_mtrr_fix_range[8].end_addr = 0xeffff; mtrrs_cached_info.ia32_mtrr_fix[9].value = hw_read_msr(IA32_MTRR_FIX4K_F0000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[9].start_addr = 0xf0000; mtrrs_cached_info.ia32_mtrr_fix_range[9].end_addr = 0xf7fff; mtrrs_cached_info.ia32_mtrr_fix[10].value = hw_read_msr(IA32_MTRR_FIX4K_F8000_ADDR); mtrrs_cached_info.ia32_mtrr_fix_range[10].start_addr = 0xf8000; mtrrs_cached_info.ia32_mtrr_fix_range[10].end_addr = 0xfffff; } for (msr_addr = IA32_MTRR_PHYSBASE0_ADDR, index = 0; index < mtrrs_abstraction_get_num_of_variable_range_regs(); msr_addr += 2, index++) { if (msr_addr > IA32_MTRR_MAX_PHYSMASK_ADDR) { MON_LOG(mask_mon, level_error, "BSP: ERROR: MTRRs Abstraction: Variable MTRRs count > %d", MTRRS_ABS_NUM_OF_VAR_RANGE_MTRRS); MON_DEADLOOP(); } mtrrs_cached_info.ia32_mtrr_var_phys_base[index].value = hw_read_msr(msr_addr); mtrrs_cached_info.ia32_mtrr_var_phys_mask[index].value = hw_read_msr(msr_addr + 1); } mtrr_msbs = ~((uint64_t)(((uint64_t)1 << addr_get_physical_address_size()) - 1)); mtrrs_cached_info.is_initialized = TRUE; return TRUE; }
UINT64 efer_msr_read_reg(void) { return hw_read_msr(IA32_MSR_EFER); }