Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/intel/vmx_msr.c
| Show First 20 Lines • Show All 318 Lines • ▼ Show 20 Lines | vmx_msr_init(void) | ||||
| */ | */ | ||||
| for (i = 0; i < 8; i++) | for (i = 0; i < 8; i++) | ||||
| turbo_ratio_limit = (turbo_ratio_limit << 8) | ratio; | turbo_ratio_limit = (turbo_ratio_limit << 8) | ratio; | ||||
| } | } | ||||
| void | void | ||||
| vmx_msr_guest_init(struct vmx *vmx, int vcpuid) | vmx_msr_guest_init(struct vmx *vmx, int vcpuid) | ||||
| { | { | ||||
| uint64_t *guest_msrs; | uint64_t *guest_msrs; | ||||
jhb: My only thought would be to maybe change this to a 'struct vmx_msrs *' and then you would have… | |||||
rgrimesUnsubmitted Done Inline ActionsI started on this, but that blows the patch up as every guest_msrs[] has to be changed in each function. The way I have it now it just touches the local pointer setup and leaves the other code lines alone. Do we really want to do this? rgrimes: I started on this, but that blows the patch up as every guest_msrs[] has to be changed in each… | |||||
jhbAuthorUnsubmitted Not Done Inline ActionsAs Patrick noted, it lets the compiler and static analyzers safely check the bounds on guest_msrs[] (which doesn't happen today, so that would be a bonus to do). While the patch is larger I do think it is clearer. jhb: As Patrick noted, it lets the compiler and static analyzers safely check the bounds on… | |||||
| guest_msrs = vmx->guest_msrs[vcpuid]; | guest_msrs = &vmx->guest_msrs[vcpuid].reg[0]; | ||||
| /* | /* | ||||
| * The permissions bitmap is shared between all vcpus so initialize it | * The permissions bitmap is shared between all vcpus so initialize it | ||||
| * once when initializing the vBSP. | * once when initializing the vBSP. | ||||
| */ | */ | ||||
| if (vcpuid == 0) { | if (vcpuid == 0) { | ||||
| guest_msr_rw(vmx, MSR_LSTAR); | guest_msr_rw(vmx, MSR_LSTAR); | ||||
| guest_msr_rw(vmx, MSR_CSTAR); | guest_msr_rw(vmx, MSR_CSTAR); | ||||
| Show All 15 Lines | guest_msrs[IDX_MSR_PAT] = PAT_VALUE(0, PAT_WRITE_BACK) | | ||||
| PAT_VALUE(7, PAT_UNCACHEABLE); | PAT_VALUE(7, PAT_UNCACHEABLE); | ||||
| return; | return; | ||||
| } | } | ||||
| void | void | ||||
| vmx_msr_guest_enter(struct vmx *vmx, int vcpuid) | vmx_msr_guest_enter(struct vmx *vmx, int vcpuid) | ||||
| { | { | ||||
| uint64_t *guest_msrs = vmx->guest_msrs[vcpuid]; | uint64_t *guest_msrs = &vmx->guest_msrs[vcpuid].reg[0]; | ||||
| /* 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, guest_msrs[IDX_MSR_LSTAR]); | wrmsr(MSR_LSTAR, guest_msrs[IDX_MSR_LSTAR]); | ||||
| wrmsr(MSR_CSTAR, guest_msrs[IDX_MSR_CSTAR]); | wrmsr(MSR_CSTAR, guest_msrs[IDX_MSR_CSTAR]); | ||||
| wrmsr(MSR_STAR, guest_msrs[IDX_MSR_STAR]); | wrmsr(MSR_STAR, guest_msrs[IDX_MSR_STAR]); | ||||
| wrmsr(MSR_SF_MASK, guest_msrs[IDX_MSR_SF_MASK]); | wrmsr(MSR_SF_MASK, guest_msrs[IDX_MSR_SF_MASK]); | ||||
| wrmsr(MSR_KGSBASE, guest_msrs[IDX_MSR_KGSBASE]); | wrmsr(MSR_KGSBASE, guest_msrs[IDX_MSR_KGSBASE]); | ||||
| } | } | ||||
| void | void | ||||
| vmx_msr_guest_exit(struct vmx *vmx, int vcpuid) | vmx_msr_guest_exit(struct vmx *vmx, int vcpuid) | ||||
| { | { | ||||
| uint64_t *guest_msrs = vmx->guest_msrs[vcpuid]; | uint64_t *guest_msrs = &vmx->guest_msrs[vcpuid].reg[0]; | ||||
| /* Save guest MSRs */ | /* Save guest MSRs */ | ||||
| guest_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); | guest_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); | ||||
| guest_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); | guest_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); | ||||
| guest_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); | guest_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); | ||||
| guest_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); | guest_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); | ||||
| guest_msrs[IDX_MSR_KGSBASE] = rdmsr(MSR_KGSBASE); | guest_msrs[IDX_MSR_KGSBASE] = rdmsr(MSR_KGSBASE); | ||||
| /* Restore host MSRs */ | /* Restore host MSRs */ | ||||
| wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); | wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); | ||||
| wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); | wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); | ||||
| wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); | wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); | ||||
| wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); | wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); | ||||
| /* MSR_KGSBASE will be restored on the way back to userspace */ | /* MSR_KGSBASE will be restored on the way back to userspace */ | ||||
| } | } | ||||
| int | int | ||||
| vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu) | vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu) | ||||
| { | { | ||||
| const uint64_t *guest_msrs; | const uint64_t *guest_msrs; | ||||
| int error; | int error; | ||||
| guest_msrs = vmx->guest_msrs[vcpuid]; | guest_msrs = &vmx->guest_msrs[vcpuid].reg[0]; | ||||
| error = 0; | error = 0; | ||||
| switch (num) { | switch (num) { | ||||
| case MSR_MCG_CAP: | case MSR_MCG_CAP: | ||||
| case MSR_MCG_STATUS: | case MSR_MCG_STATUS: | ||||
| *val = 0; | *val = 0; | ||||
| break; | break; | ||||
| case MSR_MTRRcap: | case MSR_MTRRcap: | ||||
| Show All 25 Lines | |||||
| int | int | ||||
| vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu) | vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu) | ||||
| { | { | ||||
| uint64_t *guest_msrs; | uint64_t *guest_msrs; | ||||
| uint64_t changed; | uint64_t changed; | ||||
| int error; | int error; | ||||
| guest_msrs = vmx->guest_msrs[vcpuid]; | guest_msrs = &vmx->guest_msrs[vcpuid].reg[0]; | ||||
| error = 0; | error = 0; | ||||
| switch (num) { | switch (num) { | ||||
| case MSR_MCG_CAP: | case MSR_MCG_CAP: | ||||
| case MSR_MCG_STATUS: | case MSR_MCG_STATUS: | ||||
| break; /* ignore writes */ | break; /* ignore writes */ | ||||
| case MSR_MTRRcap: | case MSR_MTRRcap: | ||||
| vm_inject_gp(vmx->vm, vcpuid); | vm_inject_gp(vmx->vm, vcpuid); | ||||
| ▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines | |||||
My only thought would be to maybe change this to a 'struct vmx_msrs *' and then you would have:
and then guest_msrs[XXX] just becomes guest_msrs.reg[XXX].