Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/intel/vmx.c
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr0_zeros_mask, CTLFLAG_RD, | ||||
&cr0_zeros_mask, 0, NULL); | &cr0_zeros_mask, 0, NULL); | ||||
static uint64_t cr4_ones_mask, cr4_zeros_mask; | static uint64_t cr4_ones_mask, cr4_zeros_mask; | ||||
SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_ones_mask, CTLFLAG_RD, | SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_ones_mask, CTLFLAG_RD, | ||||
&cr4_ones_mask, 0, NULL); | &cr4_ones_mask, 0, NULL); | ||||
SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_zeros_mask, CTLFLAG_RD, | SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr4_zeros_mask, CTLFLAG_RD, | ||||
&cr4_zeros_mask, 0, NULL); | &cr4_zeros_mask, 0, NULL); | ||||
static int vmx_no_patmsr; | |||||
static int vmx_initialized; | static int vmx_initialized; | ||||
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initialized, CTLFLAG_RD, | SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initialized, CTLFLAG_RD, | ||||
&vmx_initialized, 0, "Intel VMX initialized"); | &vmx_initialized, 0, "Intel VMX initialized"); | ||||
/* | /* | ||||
* Optional capabilities | * Optional capabilities | ||||
*/ | */ | ||||
static SYSCTL_NODE(_hw_vmm_vmx, OID_AUTO, cap, CTLFLAG_RW, NULL, NULL); | |||||
static int vmx_patmsr; | |||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, patmsr, CTLFLAG_RD, &vmx_patmsr, 0, | |||||
"PAT MSR saved and restored in VCMS"); | |||||
static int cap_halt_exit; | static int cap_halt_exit; | ||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, halt_exit, CTLFLAG_RD, &cap_halt_exit, 0, | |||||
"HLT triggers a VM-exit"); | |||||
static int cap_pause_exit; | static int cap_pause_exit; | ||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, pause_exit, CTLFLAG_RD, &cap_pause_exit, | |||||
0, "PAUSE triggers a VM-exit"); | |||||
static int cap_unrestricted_guest; | static int cap_unrestricted_guest; | ||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, unrestricted_guest, CTLFLAG_RD, | |||||
&cap_unrestricted_guest, 0, "Unrestricted guests"); | |||||
static int cap_monitor_trap; | static int cap_monitor_trap; | ||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, monitor_trap, CTLFLAG_RD, | |||||
&cap_monitor_trap, 0, "Monitor trap flag"); | |||||
static int cap_invpcid; | static int cap_invpcid; | ||||
SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, invpcid, CTLFLAG_RD, &cap_invpcid, | |||||
0, "Guests are allowed to use INVPCID"); | |||||
static int virtual_interrupt_delivery; | static int virtual_interrupt_delivery; | ||||
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD, | SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, virtual_interrupt_delivery, CTLFLAG_RD, | ||||
&virtual_interrupt_delivery, 0, "APICv virtual interrupt delivery support"); | &virtual_interrupt_delivery, 0, "APICv virtual interrupt delivery support"); | ||||
static int posted_interrupts; | static int posted_interrupts; | ||||
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupts, CTLFLAG_RD, | SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, posted_interrupts, CTLFLAG_RD, | ||||
&posted_interrupts, 0, "APICv posted interrupt support"); | &posted_interrupts, 0, "APICv posted interrupt support"); | ||||
static int pirvec; | static int pirvec; | ||||
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD, | SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, posted_interrupt_vector, CTLFLAG_RD, | ||||
&pirvec, 0, "APICv posted interrupt vector"); | &pirvec, 0, "APICv posted interrupt vector"); | ||||
static struct unrhdr *vpid_unr; | static struct unrhdr *vpid_unr; | ||||
static u_int vpid_alloc_failed; | static u_int vpid_alloc_failed; | ||||
▲ Show 20 Lines • Show All 432 Lines • ▼ Show 20 Lines | error = vmx_set_ctlreg(MSR_VMX_PINBASED_CTLS, | ||||
PINBASED_CTLS_ZERO_SETTING, &pinbased_ctls); | PINBASED_CTLS_ZERO_SETTING, &pinbased_ctls); | ||||
if (error) { | if (error) { | ||||
printf("vmx_init: processor does not support desired " | printf("vmx_init: processor does not support desired " | ||||
"pin-based controls\n"); | "pin-based controls\n"); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* Check support for VM-exit controls */ | /* Check support for VM-exit controls */ | ||||
vmx_patmsr = 1; | |||||
error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, MSR_VMX_TRUE_EXIT_CTLS, | error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, MSR_VMX_TRUE_EXIT_CTLS, | ||||
VM_EXIT_CTLS_ONE_SETTING, | VM_EXIT_CTLS_ONE_SETTING, | ||||
VM_EXIT_CTLS_ZERO_SETTING, | VM_EXIT_CTLS_ZERO_SETTING, | ||||
&exit_ctls); | &exit_ctls); | ||||
if (error) { | if (error) { | ||||
/* Try again without the PAT MSR bits */ | /* Try again without the PAT MSR bits */ | ||||
error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, | error = vmx_set_ctlreg(MSR_VMX_EXIT_CTLS, | ||||
MSR_VMX_TRUE_EXIT_CTLS, | MSR_VMX_TRUE_EXIT_CTLS, | ||||
VM_EXIT_CTLS_ONE_SETTING_NO_PAT, | VM_EXIT_CTLS_ONE_SETTING_NO_PAT, | ||||
VM_EXIT_CTLS_ZERO_SETTING, | VM_EXIT_CTLS_ZERO_SETTING, | ||||
&exit_ctls); | &exit_ctls); | ||||
if (error) { | if (error) { | ||||
printf("vmx_init: processor does not support desired " | printf("vmx_init: processor does not support desired " | ||||
"exit controls\n"); | "exit controls\n"); | ||||
return (error); | return (error); | ||||
} else { | } else { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("vmm: PAT MSR access not supported\n"); | printf("vmm: PAT MSR access not supported\n"); | ||||
guest_msr_valid(MSR_PAT); | guest_msr_valid(MSR_PAT); | ||||
vmx_no_patmsr = 1; | vmx_patmsr = 0; | ||||
} | } | ||||
} | } | ||||
/* Check support for VM-entry controls */ | /* Check support for VM-entry controls */ | ||||
if (!vmx_no_patmsr) { | if (vmx_patmsr) { | ||||
error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS, | error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS, | ||||
MSR_VMX_TRUE_ENTRY_CTLS, | MSR_VMX_TRUE_ENTRY_CTLS, | ||||
VM_ENTRY_CTLS_ONE_SETTING, | VM_ENTRY_CTLS_ONE_SETTING, | ||||
VM_ENTRY_CTLS_ZERO_SETTING, | VM_ENTRY_CTLS_ZERO_SETTING, | ||||
&entry_ctls); | &entry_ctls); | ||||
} else { | } else { | ||||
error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS, | error = vmx_set_ctlreg(MSR_VMX_ENTRY_CTLS, | ||||
MSR_VMX_TRUE_ENTRY_CTLS, | MSR_VMX_TRUE_ENTRY_CTLS, | ||||
▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | vmx_vminit(struct vm *vm, pmap_t pmap) | ||||
/* | /* | ||||
* MSR_PAT is saved and restored in the guest VMCS are on a VM exit | * MSR_PAT is saved and restored in the guest VMCS are on a VM exit | ||||
* and entry respectively. It is also restored from the host VMCS | * and entry respectively. It is also restored from the host VMCS | ||||
* area on a VM exit. However, if running on a system with no | * area on a VM exit. However, if running on a system with no | ||||
* MSR_PAT save/restore support, leave access disabled so accesses | * MSR_PAT save/restore support, leave access disabled so accesses | ||||
* will be trapped. | * will be trapped. | ||||
*/ | */ | ||||
if (!vmx_no_patmsr && guest_msr_rw(vmx, MSR_PAT)) | if (vmx_patmsr && guest_msr_rw(vmx, MSR_PAT)) | ||||
panic("vmx_vminit: error setting guest pat msr access"); | panic("vmx_vminit: error setting guest pat msr access"); | ||||
vpid_alloc(vpid, VM_MAXCPU); | vpid_alloc(vpid, VM_MAXCPU); | ||||
if (virtual_interrupt_delivery) { | if (virtual_interrupt_delivery) { | ||||
error = vm_map_mmio(vm, DEFAULT_APIC_BASE, PAGE_SIZE, | error = vm_map_mmio(vm, DEFAULT_APIC_BASE, PAGE_SIZE, | ||||
APIC_ACCESS_ADDRESS); | APIC_ACCESS_ADDRESS); | ||||
/* XXX this should really return an error to the caller */ | /* XXX this should really return an error to the caller */ | ||||
▲ Show 20 Lines • Show All 2,360 Lines • Show Last 20 Lines |