Index: sys/amd64/vmm/intel/vmx.h =================================================================== --- sys/amd64/vmm/intel/vmx.h (revision 282201) +++ sys/amd64/vmm/intel/vmx.h (working copy) @@ -104,6 +104,7 @@ IDX_MSR_SF_MASK, IDX_MSR_KGSBASE, IDX_MSR_PAT, + IDX_MSR_MTRRdefType, GUEST_MSR_NUM /* must be the last enumeration */ }; Index: sys/amd64/vmm/intel/vmx_msr.c =================================================================== --- sys/amd64/vmm/intel/vmx_msr.c (revision 282201) +++ sys/amd64/vmm/intel/vmx_msr.c (working copy) @@ -249,6 +249,25 @@ return (true); } +static bool +mtrrdef_valid(uint64_t val) +{ + uint64_t rsvd; + uint8_t type; + + /* Reserved bits cannot be set to non-zero values */ + rsvd = ~(MTRR_DEF_ENABLE | MTRR_DEF_FIXED_ENABLE | MTRR_DEF_TYPE); + if (val & rsvd) + return (false); + + /* Valid memory types are 0, 1, 4, 5 or 6 */ + type = val & MTRR_DEF_TYPE; + if (type == 2 || type == 3 || type > 6) + return (false); + + return (true); +} + void vmx_msr_init(void) { @@ -396,6 +415,17 @@ error = 0; switch (num) { + case MSR_MTRRcap: + *val = 0; + break; + case MSR_MTRRdefType: + *val = guest_msrs[IDX_MSR_MTRRdefType]; + break; + case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8: + case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: + case MSR_MTRR64kBase: + *val = 0; + break; case MSR_IA32_MISC_ENABLE: *val = misc_enable; break; @@ -427,6 +457,19 @@ error = 0; switch (num) { + case MSR_MTRRcap: + vm_inject_gp(vmx->vm, vcpuid); + break; + case MSR_MTRRdefType: + if (mtrrdef_valid(val)) + guest_msrs[IDX_MSR_MTRRdefType] = val; + else + vm_inject_gp(vmx->vm, vcpuid); + break; + case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8: + case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: + case MSR_MTRR64kBase: + break; /* Ignore writes the the MTRRs */ case MSR_IA32_MISC_ENABLE: changed = val ^ misc_enable; /* Index: sys/amd64/vmm/x86.c =================================================================== --- sys/amd64/vmm/x86.c (revision 282201) +++ sys/amd64/vmm/x86.c (working copy) @@ -289,9 +289,8 @@ /* * Machine check handling is done in the host. - * Hide MTRR capability. */ - regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR); + regs[3] &= ~(CPUID_MCA | CPUID_MCE); /* * Hide the debug store capability.