diff --git a/src/lib/vmm/intel/vmx.c b/src/lib/vmm/intel/vmx.c index 7193ed0f..1aa62d24 100644 --- a/src/lib/vmm/intel/vmx.c +++ b/src/lib/vmm/intel/vmx.c @@ -496,60 +496,6 @@ vmx_init(void) xhyve_abort("hv_vm_create unknown error %d\n", error); } - /* Check support for primary processor-based VM-execution controls */ - error = vmx_set_ctlreg(HV_VMX_CAP_PROCBASED, - PROCBASED_CTLS_ONE_SETTING, - PROCBASED_CTLS_ZERO_SETTING, &procbased_ctls); - if (error) { - printf("vmx_init: processor does not support desired primary " - "processor-based controls\n"); - return (error); - } - - /* Clear the processor-based ctl bits that are set on demand */ - procbased_ctls &= ~PROCBASED_CTLS_WINDOW_SETTING; - - /* Check support for secondary processor-based VM-execution controls */ - error = vmx_set_ctlreg(HV_VMX_CAP_PROCBASED2, - PROCBASED_CTLS2_ONE_SETTING, - PROCBASED_CTLS2_ZERO_SETTING, &procbased_ctls2); - if (error) { - printf("vmx_init: processor does not support desired secondary " - "processor-based controls\n"); - return (error); - } - - /* Check support for pin-based VM-execution controls */ - error = vmx_set_ctlreg(HV_VMX_CAP_PINBASED, - PINBASED_CTLS_ONE_SETTING, - PINBASED_CTLS_ZERO_SETTING, &pinbased_ctls); - if (error) { - printf("vmx_init: processor does not support desired " - "pin-based controls\n"); - return (error); - } - - /* Check support for VM-exit controls */ - error = vmx_set_ctlreg(HV_VMX_CAP_EXIT, - VM_EXIT_CTLS_ONE_SETTING, - VM_EXIT_CTLS_ZERO_SETTING, - &exit_ctls); - if (error) { - printf("vmx_init: processor does not support desired " - "exit controls\n"); - return (error); - } - - /* Check support for VM-entry controls */ - error = vmx_set_ctlreg(HV_VMX_CAP_ENTRY, - VM_ENTRY_CTLS_ONE_SETTING, VM_ENTRY_CTLS_ZERO_SETTING, - &entry_ctls); - if (error) { - printf("vmx_init: processor does not support desired " - "entry controls\n"); - return (error); - } - /* * Check support for optional features by testing them * as individual bits @@ -649,6 +595,65 @@ vmx_vcpu_init(void *arg, int vcpuid) { vmx_msr_guest_init(vmx, vcpuid); + /* Check support for primary processor-based VM-execution controls */ + procbased_ctls = (uint32_t) vmcs_read(vcpuid, HV_VMX_CAP_PROCBASED); + error = vmx_set_ctlreg(HV_VMX_CAP_PROCBASED, + PROCBASED_CTLS_ONE_SETTING, + PROCBASED_CTLS_ZERO_SETTING, &procbased_ctls); + if (error) { + printf("vmx_init: processor does not support desired primary " + "processor-based controls\n"); + return (error); + } + + /* Clear the processor-based ctl bits that are set on demand */ + procbased_ctls &= ~PROCBASED_CTLS_WINDOW_SETTING; + + /* Check support for secondary processor-based VM-execution controls */ + procbased_ctls2 = (uint32_t) vmcs_read(vcpuid, HV_VMX_CAP_PROCBASED2); + error = vmx_set_ctlreg(HV_VMX_CAP_PROCBASED2, + PROCBASED_CTLS2_ONE_SETTING, + PROCBASED_CTLS2_ZERO_SETTING, &procbased_ctls2); + if (error) { + printf("vmx_init: processor does not support desired secondary " + "processor-based controls\n"); + return (error); + } + + /* Check support for pin-based VM-execution controls */ + pinbased_ctls = (uint32_t) vmcs_read(vcpuid, HV_VMX_CAP_PINBASED); + error = vmx_set_ctlreg(HV_VMX_CAP_PINBASED, + PINBASED_CTLS_ONE_SETTING, + PINBASED_CTLS_ZERO_SETTING, &pinbased_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "pin-based controls\n"); + return (error); + } + + /* Check support for VM-exit controls */ + exit_ctls = (uint32_t) vmcs_read(vcpuid, HV_VMX_CAP_EXIT); + error = vmx_set_ctlreg(HV_VMX_CAP_EXIT, + VM_EXIT_CTLS_ONE_SETTING, + VM_EXIT_CTLS_ZERO_SETTING, + &exit_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "exit controls\n"); + return (error); + } + + /* Check support for VM-entry controls */ + entry_ctls = (uint32_t) vmcs_read(vcpuid, HV_VMX_CAP_ENTRY); + error = vmx_set_ctlreg(HV_VMX_CAP_ENTRY, + VM_ENTRY_CTLS_ONE_SETTING, VM_ENTRY_CTLS_ZERO_SETTING, + &entry_ctls); + if (error) { + printf("vmx_init: processor does not support desired " + "entry controls\n"); + return (error); + } + vmcs_write(vcpuid, VMCS_PIN_BASED_CTLS, pinbased_ctls); vmcs_write(vcpuid, VMCS_PRI_PROC_BASED_CTLS, procbased_ctls); vmcs_write(vcpuid, VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2); diff --git a/src/lib/vmm/intel/vmx_msr.c b/src/lib/vmm/intel/vmx_msr.c index 3f3645a6..b7c0c1a1 100644 --- a/src/lib/vmm/intel/vmx_msr.c +++ b/src/lib/vmm/intel/vmx_msr.c @@ -96,17 +96,17 @@ int vmx_set_ctlreg(hv_vmx_capability_t cap_field, uint32_t ones_mask, } *retval |= 1 << i; } else { - /* don't care */ + /* Hypervisor doesn't care */ if (zeros_mask & (1 << i)){ *retval &= ~(1 << i); } else if (ones_mask & (1 << i)) { *retval |= 1 << i; } else { - /* XXX: don't allow unspecified don't cares */ + /* We don't care either: inherit the system default */ fprintf(stderr, "vmx_set_ctlreg: cap_field: %d bit: %d unspecified " - "don't care\n", cap_field, i); - return (EINVAL); + "don't care: bit is %d\n", cap_field, i, + (*retval & (1 << i))?1:0); } } }