Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/intel/vmx.c
Show All 40 Lines | |||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/pcpu.h> | #include <sys/pcpu.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/reg.h> | #include <sys/reg.h> | ||||
#include <sys/smr.h> | #include <sys/smr.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_extern.h> | |||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <machine/psl.h> | #include <machine/psl.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/segments.h> | #include <machine/segments.h> | ||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <machine/specialreg.h> | #include <machine/specialreg.h> | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
bool vmx_have_msr_tsc_aux; | bool vmx_have_msr_tsc_aux; | ||||
SYSCTL_DECL(_hw_vmm); | SYSCTL_DECL(_hw_vmm); | ||||
SYSCTL_NODE(_hw_vmm, OID_AUTO, vmx, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, | SYSCTL_NODE(_hw_vmm, OID_AUTO, vmx, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, | ||||
NULL); | NULL); | ||||
int vmxon_enabled[MAXCPU]; | int vmxon_enabled[MAXCPU]; | ||||
static char vmxon_region[MAXCPU][PAGE_SIZE] __aligned(PAGE_SIZE); | static uint8_t *vmxon_region; | ||||
static uint32_t pinbased_ctls, procbased_ctls, procbased_ctls2; | static uint32_t pinbased_ctls, procbased_ctls, procbased_ctls2; | ||||
static uint32_t exit_ctls, entry_ctls; | static uint32_t exit_ctls, entry_ctls; | ||||
static uint64_t cr0_ones_mask, cr0_zeros_mask; | static uint64_t cr0_ones_mask, cr0_zeros_mask; | ||||
SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr0_ones_mask, CTLFLAG_RD, | SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr0_ones_mask, CTLFLAG_RD, | ||||
&cr0_ones_mask, 0, NULL); | &cr0_ones_mask, 0, NULL); | ||||
SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr0_zeros_mask, CTLFLAG_RD, | SYSCTL_ULONG(_hw_vmm_vmx, OID_AUTO, cr0_zeros_mask, CTLFLAG_RD, | ||||
▲ Show 20 Lines • Show All 467 Lines • ▼ Show 20 Lines | if (vpid_unr != NULL) { | ||||
delete_unrhdr(vpid_unr); | delete_unrhdr(vpid_unr); | ||||
vpid_unr = NULL; | vpid_unr = NULL; | ||||
} | } | ||||
if (nmi_flush_l1d_sw == 1) | if (nmi_flush_l1d_sw == 1) | ||||
nmi_flush_l1d_sw = 0; | nmi_flush_l1d_sw = 0; | ||||
smp_rendezvous(NULL, vmx_disable, NULL, NULL); | smp_rendezvous(NULL, vmx_disable, NULL, NULL); | ||||
kmem_free(vmxon_region, (mp_maxid + 1) * PAGE_SIZE); | |||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
vmx_enable(void *arg __unused) | vmx_enable(void *arg __unused) | ||||
{ | { | ||||
int error; | int error; | ||||
uint64_t feature_control; | uint64_t feature_control; | ||||
feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL); | feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL); | ||||
if ((feature_control & IA32_FEATURE_CONTROL_LOCK) == 0 || | if ((feature_control & IA32_FEATURE_CONTROL_LOCK) == 0 || | ||||
(feature_control & IA32_FEATURE_CONTROL_VMX_EN) == 0) { | (feature_control & IA32_FEATURE_CONTROL_VMX_EN) == 0) { | ||||
wrmsr(MSR_IA32_FEATURE_CONTROL, | wrmsr(MSR_IA32_FEATURE_CONTROL, | ||||
feature_control | IA32_FEATURE_CONTROL_VMX_EN | | feature_control | IA32_FEATURE_CONTROL_VMX_EN | | ||||
IA32_FEATURE_CONTROL_LOCK); | IA32_FEATURE_CONTROL_LOCK); | ||||
} | } | ||||
load_cr4(rcr4() | CR4_VMXE); | load_cr4(rcr4() | CR4_VMXE); | ||||
*(uint32_t *)vmxon_region[curcpu] = vmx_revision(); | *(uint32_t *)&vmxon_region[curcpu * PAGE_SIZE] = vmx_revision(); | ||||
error = vmxon(vmxon_region[curcpu]); | error = vmxon(&vmxon_region[curcpu * PAGE_SIZE]); | ||||
if (error == 0) | if (error == 0) | ||||
vmxon_enabled[curcpu] = 1; | vmxon_enabled[curcpu] = 1; | ||||
} | } | ||||
static void | static void | ||||
vmx_modresume(void) | vmx_modresume(void) | ||||
{ | { | ||||
if (vmxon_enabled[curcpu]) | if (vmxon_enabled[curcpu]) | ||||
vmxon(vmxon_region[curcpu]); | vmxon(&vmxon_region[curcpu * PAGE_SIZE]); | ||||
} | } | ||||
static int | static int | ||||
vmx_modinit(int ipinum) | vmx_modinit(int ipinum) | ||||
{ | { | ||||
int error; | int error; | ||||
uint64_t basic, fixed0, fixed1, feature_control; | uint64_t basic, fixed0, fixed1, feature_control; | ||||
uint32_t tmp, procbased2_vid_bits; | uint32_t tmp, procbased2_vid_bits; | ||||
▲ Show 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | vmx_modinit(int ipinum) | ||||
cr4_ones_mask = fixed0 & fixed1; | cr4_ones_mask = fixed0 & fixed1; | ||||
cr4_zeros_mask = ~fixed0 & ~fixed1; | cr4_zeros_mask = ~fixed0 & ~fixed1; | ||||
vpid_init(); | vpid_init(); | ||||
vmx_msr_init(); | vmx_msr_init(); | ||||
/* enable VMX operation */ | /* enable VMX operation */ | ||||
vmxon_region = kmem_malloc((mp_maxid + 1) * PAGE_SIZE, | |||||
M_WAITOK | M_ZERO); | |||||
smp_rendezvous(NULL, vmx_enable, NULL, NULL); | smp_rendezvous(NULL, vmx_enable, NULL, NULL); | ||||
vmx_initialized = 1; | vmx_initialized = 1; | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 3,285 Lines • Show Last 20 Lines |