Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/intel/vmx_msr.c
Show First 20 Lines • Show All 338 Lines • ▼ Show 20 Lines | vcpu->guest_msrs[IDX_MSR_PAT] = PAT_VALUE(0, PAT_WRITE_BACK) | | ||||
PAT_VALUE(5, PAT_WRITE_THROUGH) | | PAT_VALUE(5, PAT_WRITE_THROUGH) | | ||||
PAT_VALUE(6, PAT_UNCACHED) | | PAT_VALUE(6, PAT_UNCACHED) | | ||||
PAT_VALUE(7, PAT_UNCACHEABLE); | PAT_VALUE(7, PAT_UNCACHEABLE); | ||||
return; | return; | ||||
} | } | ||||
void | void | ||||
vmx_msr_guest_enter(struct vmx *vmx, struct vmx_vcpu *vcpu) | vmx_msr_guest_enter(struct vmx_vcpu *vcpu) | ||||
{ | { | ||||
/* Save host MSRs (in particular, KGSBASE) and restore guest MSRs */ | /* Save host MSRs (in particular, KGSBASE) and restore guest MSRs */ | ||||
update_pcb_bases(curpcb); | update_pcb_bases(curpcb); | ||||
wrmsr(MSR_LSTAR, vcpu->guest_msrs[IDX_MSR_LSTAR]); | wrmsr(MSR_LSTAR, vcpu->guest_msrs[IDX_MSR_LSTAR]); | ||||
wrmsr(MSR_CSTAR, vcpu->guest_msrs[IDX_MSR_CSTAR]); | wrmsr(MSR_CSTAR, vcpu->guest_msrs[IDX_MSR_CSTAR]); | ||||
wrmsr(MSR_STAR, vcpu->guest_msrs[IDX_MSR_STAR]); | wrmsr(MSR_STAR, vcpu->guest_msrs[IDX_MSR_STAR]); | ||||
wrmsr(MSR_SF_MASK, vcpu->guest_msrs[IDX_MSR_SF_MASK]); | wrmsr(MSR_SF_MASK, vcpu->guest_msrs[IDX_MSR_SF_MASK]); | ||||
wrmsr(MSR_KGSBASE, vcpu->guest_msrs[IDX_MSR_KGSBASE]); | wrmsr(MSR_KGSBASE, vcpu->guest_msrs[IDX_MSR_KGSBASE]); | ||||
} | } | ||||
void | void | ||||
vmx_msr_guest_enter_tsc_aux(struct vmx *vmx, struct vmx_vcpu *vcpu) | vmx_msr_guest_enter_tsc_aux(struct vmx *vmx, struct vmx_vcpu *vcpu) | ||||
{ | { | ||||
uint64_t guest_tsc_aux = vcpu->guest_msrs[IDX_MSR_TSC_AUX]; | uint64_t guest_tsc_aux = vcpu->guest_msrs[IDX_MSR_TSC_AUX]; | ||||
uint32_t host_aux = cpu_auxmsr(); | uint32_t host_aux = cpu_auxmsr(); | ||||
if (vmx_have_msr_tsc_aux && guest_tsc_aux != host_aux) | if (vmx_have_msr_tsc_aux && guest_tsc_aux != host_aux) | ||||
wrmsr(MSR_TSC_AUX, guest_tsc_aux); | wrmsr(MSR_TSC_AUX, guest_tsc_aux); | ||||
} | } | ||||
void | void | ||||
vmx_msr_guest_exit(struct vmx *vmx, struct vmx_vcpu *vcpu) | vmx_msr_guest_exit(struct vmx_vcpu *vcpu) | ||||
{ | { | ||||
/* Save guest MSRs */ | /* Save guest MSRs */ | ||||
vcpu->guest_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); | vcpu->guest_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); | ||||
vcpu->guest_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); | vcpu->guest_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); | ||||
vcpu->guest_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); | vcpu->guest_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); | ||||
vcpu->guest_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); | vcpu->guest_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); | ||||
vcpu->guest_msrs[IDX_MSR_KGSBASE] = rdmsr(MSR_KGSBASE); | vcpu->guest_msrs[IDX_MSR_KGSBASE] = rdmsr(MSR_KGSBASE); | ||||
Show All 20 Lines | if (vmx_have_msr_tsc_aux && guest_tsc_aux != host_aux) | ||||
* contains the current value since it is updated whenever | * contains the current value since it is updated whenever | ||||
* the guest writes to it (which is expected to be very | * the guest writes to it (which is expected to be very | ||||
* rare). | * rare). | ||||
*/ | */ | ||||
wrmsr(MSR_TSC_AUX, host_aux); | wrmsr(MSR_TSC_AUX, host_aux); | ||||
} | } | ||||
int | int | ||||
vmx_rdmsr(struct vmx *vmx, struct vmx_vcpu *vcpu, u_int num, uint64_t *val, | vmx_rdmsr(struct vmx_vcpu *vcpu, u_int num, uint64_t *val, bool *retu) | ||||
bool *retu) | |||||
{ | { | ||||
int error; | int error; | ||||
error = 0; | error = 0; | ||||
switch (num) { | switch (num) { | ||||
case MSR_MCG_CAP: | case MSR_MCG_CAP: | ||||
case MSR_MCG_STATUS: | case MSR_MCG_STATUS: | ||||
Show All 25 Lines | vmx_rdmsr(struct vmx_vcpu *vcpu, u_int num, uint64_t *val, bool *retu) | ||||
default: | default: | ||||
error = EINVAL; | error = EINVAL; | ||||
break; | break; | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
vmx_wrmsr(struct vmx *vmx, struct vmx_vcpu *vcpu, u_int num, uint64_t val, | vmx_wrmsr(struct vmx_vcpu *vcpu, u_int num, uint64_t val, bool *retu) | ||||
bool *retu) | |||||
{ | { | ||||
uint64_t changed; | uint64_t changed; | ||||
int error; | int error; | ||||
error = 0; | error = 0; | ||||
switch (num) { | switch (num) { | ||||
case MSR_MCG_CAP: | case MSR_MCG_CAP: | ||||
Show All 31 Lines | case MSR_IA32_MISC_ENABLE: | ||||
break; | break; | ||||
case MSR_PAT: | case MSR_PAT: | ||||
if (pat_valid(val)) | if (pat_valid(val)) | ||||
vcpu->guest_msrs[IDX_MSR_PAT] = val; | vcpu->guest_msrs[IDX_MSR_PAT] = val; | ||||
else | else | ||||
vm_inject_gp(vcpu->vcpu); | vm_inject_gp(vcpu->vcpu); | ||||
break; | break; | ||||
case MSR_TSC: | case MSR_TSC: | ||||
error = vmx_set_tsc_offset(vmx, vcpu, val - rdtsc()); | error = vmx_set_tsc_offset(vcpu, val - rdtsc()); | ||||
break; | break; | ||||
case MSR_TSC_AUX: | case MSR_TSC_AUX: | ||||
if (vmx_have_msr_tsc_aux) | if (vmx_have_msr_tsc_aux) | ||||
/* | /* | ||||
* vmx_msr_guest_enter_tsc_aux() will apply this | * vmx_msr_guest_enter_tsc_aux() will apply this | ||||
* value when it is called immediately before guest | * value when it is called immediately before guest | ||||
* entry. | * entry. | ||||
*/ | */ | ||||
Show All 11 Lines |