Split the VMCS setup between 'vmcs_init()' that does initialization and
'vmx_vminit()' that does customization. This makes it easier to turn on optional features (e.g. APICv) without having to keep adding new parameters to 'vmcs_set_defaults()'. Reviewed by: grehan@
This commit is contained in:
parent
9f8536f282
commit
35066c7a68
@ -315,11 +315,7 @@ vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count)
|
||||
}
|
||||
|
||||
int
|
||||
vmcs_set_defaults(struct vmcs *vmcs,
|
||||
u_long host_rip, u_long host_rsp, uint64_t eptp,
|
||||
uint32_t pinbased_ctls, uint32_t procbased_ctls,
|
||||
uint32_t procbased_ctls2, uint32_t exit_ctls,
|
||||
uint32_t entry_ctls, u_long msr_bitmap, uint16_t vpid)
|
||||
vmcs_init(struct vmcs *vmcs)
|
||||
{
|
||||
int error, codesel, datasel, tsssel;
|
||||
u_long cr0, cr4, efer;
|
||||
@ -335,22 +331,6 @@ vmcs_set_defaults(struct vmcs *vmcs,
|
||||
*/
|
||||
VMPTRLD(vmcs);
|
||||
|
||||
/*
|
||||
* Load the VMX controls
|
||||
*/
|
||||
if ((error = vmwrite(VMCS_PIN_BASED_CTLS, pinbased_ctls)) != 0)
|
||||
goto done;
|
||||
if ((error = vmwrite(VMCS_PRI_PROC_BASED_CTLS, procbased_ctls)) != 0)
|
||||
goto done;
|
||||
if ((error = vmwrite(VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2)) != 0)
|
||||
goto done;
|
||||
if ((error = vmwrite(VMCS_EXIT_CTLS, exit_ctls)) != 0)
|
||||
goto done;
|
||||
if ((error = vmwrite(VMCS_ENTRY_CTLS, entry_ctls)) != 0)
|
||||
goto done;
|
||||
|
||||
/* Guest state */
|
||||
|
||||
/* Initialize guest IA32_PAT MSR with the default value */
|
||||
pat = PAT_VALUE(0, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(1, PAT_WRITE_THROUGH) |
|
||||
@ -422,23 +402,7 @@ vmcs_set_defaults(struct vmcs *vmcs,
|
||||
goto done;
|
||||
|
||||
/* instruction pointer */
|
||||
if ((error = vmwrite(VMCS_HOST_RIP, host_rip)) != 0)
|
||||
goto done;
|
||||
|
||||
/* stack pointer */
|
||||
if ((error = vmwrite(VMCS_HOST_RSP, host_rsp)) != 0)
|
||||
goto done;
|
||||
|
||||
/* eptp */
|
||||
if ((error = vmwrite(VMCS_EPTP, eptp)) != 0)
|
||||
goto done;
|
||||
|
||||
/* vpid */
|
||||
if ((error = vmwrite(VMCS_VPID, vpid)) != 0)
|
||||
goto done;
|
||||
|
||||
/* msr bitmap */
|
||||
if ((error = vmwrite(VMCS_MSR_BITMAP, msr_bitmap)) != 0)
|
||||
if ((error = vmwrite(VMCS_HOST_RIP, (u_long)vmx_exit_guest)) != 0)
|
||||
goto done;
|
||||
|
||||
/* exception bitmap */
|
||||
|
@ -46,12 +46,7 @@ struct msr_entry {
|
||||
};
|
||||
|
||||
int vmcs_set_msr_save(struct vmcs *vmcs, u_long g_area, u_int g_count);
|
||||
int vmcs_set_defaults(struct vmcs *vmcs, u_long host_rip, u_long host_rsp,
|
||||
uint64_t eptp,
|
||||
uint32_t pinbased_ctls, uint32_t procbased_ctls,
|
||||
uint32_t procbased_ctls2, uint32_t exit_ctls,
|
||||
uint32_t entry_ctls, u_long msr_bitmap,
|
||||
uint16_t vpid);
|
||||
int vmcs_init(struct vmcs *vmcs);
|
||||
int vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t *rv);
|
||||
int vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val);
|
||||
int vmcs_getdesc(struct vmcs *vmcs, int ident,
|
||||
|
@ -678,6 +678,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
|
||||
uint16_t vpid[VM_MAXCPU];
|
||||
int i, error, guest_msr_count;
|
||||
struct vmx *vmx;
|
||||
struct vmcs *vmcs;
|
||||
|
||||
vmx = malloc(sizeof(struct vmx), M_VMX, M_WAITOK | M_ZERO);
|
||||
if ((uintptr_t)vmx & PAGE_MASK) {
|
||||
@ -743,26 +744,30 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
|
||||
vpid_alloc(vpid, VM_MAXCPU);
|
||||
|
||||
for (i = 0; i < VM_MAXCPU; i++) {
|
||||
vmx->vmcs[i].identifier = vmx_revision();
|
||||
error = vmclear(&vmx->vmcs[i]);
|
||||
vmcs = &vmx->vmcs[i];
|
||||
vmcs->identifier = vmx_revision();
|
||||
error = vmclear(vmcs);
|
||||
if (error != 0) {
|
||||
panic("vmx_vminit: vmclear error %d on vcpu %d\n",
|
||||
error, i);
|
||||
}
|
||||
|
||||
error = vmcs_set_defaults(&vmx->vmcs[i],
|
||||
(u_long)vmx_exit_guest,
|
||||
(u_long)&vmx->ctx[i],
|
||||
vmx->eptp,
|
||||
pinbased_ctls,
|
||||
procbased_ctls,
|
||||
procbased_ctls2,
|
||||
exit_ctls, entry_ctls,
|
||||
vtophys(vmx->msr_bitmap),
|
||||
vpid[i]);
|
||||
error = vmcs_init(vmcs);
|
||||
KASSERT(error == 0, ("vmcs_init error %d", error));
|
||||
|
||||
if (error != 0)
|
||||
panic("vmx_vminit: vmcs_set_defaults error %d", error);
|
||||
VMPTRLD(vmcs);
|
||||
error = 0;
|
||||
error += vmwrite(VMCS_HOST_RSP, (u_long)&vmx->ctx[i]);
|
||||
error += vmwrite(VMCS_EPTP, vmx->eptp);
|
||||
error += vmwrite(VMCS_PIN_BASED_CTLS, pinbased_ctls);
|
||||
error += vmwrite(VMCS_PRI_PROC_BASED_CTLS, procbased_ctls);
|
||||
error += vmwrite(VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2);
|
||||
error += vmwrite(VMCS_EXIT_CTLS, exit_ctls);
|
||||
error += vmwrite(VMCS_ENTRY_CTLS, entry_ctls);
|
||||
error += vmwrite(VMCS_MSR_BITMAP, vtophys(vmx->msr_bitmap));
|
||||
error += vmwrite(VMCS_VPID, vpid[i]);
|
||||
VMCLEAR(vmcs);
|
||||
KASSERT(error == 0, ("vmx_vminit: error customizing the vmcs"));
|
||||
|
||||
vmx->cap[i].set = 0;
|
||||
vmx->cap[i].proc_ctls = procbased_ctls;
|
||||
@ -773,9 +778,8 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
|
||||
|
||||
msr_save_area_init(vmx->guest_msrs[i], &guest_msr_count);
|
||||
|
||||
error = vmcs_set_msr_save(&vmx->vmcs[i],
|
||||
vtophys(vmx->guest_msrs[i]),
|
||||
guest_msr_count);
|
||||
error = vmcs_set_msr_save(vmcs, vtophys(vmx->guest_msrs[i]),
|
||||
guest_msr_count);
|
||||
if (error != 0)
|
||||
panic("vmcs_set_msr_save error %d", error);
|
||||
|
||||
@ -785,11 +789,11 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
|
||||
* CR0 - 0x60000010
|
||||
* CR4 - 0
|
||||
*/
|
||||
error = vmx_setup_cr0_shadow(&vmx->vmcs[i], 0x60000010);
|
||||
error = vmx_setup_cr0_shadow(vmcs, 0x60000010);
|
||||
if (error != 0)
|
||||
panic("vmx_setup_cr0_shadow %d", error);
|
||||
|
||||
error = vmx_setup_cr4_shadow(&vmx->vmcs[i], 0);
|
||||
error = vmx_setup_cr4_shadow(vmcs, 0);
|
||||
if (error != 0)
|
||||
panic("vmx_setup_cr4_shadow %d", error);
|
||||
|
||||
@ -1455,7 +1459,7 @@ vmx_run(void *arg, int vcpu, register_t startrip, pmap_t pmap)
|
||||
* from a different process than the one that actually runs it.
|
||||
*
|
||||
* If the life of a virtual machine was spent entirely in the context
|
||||
* of a single process we could do this once in vmcs_set_defaults().
|
||||
* of a single process we could do this once in vmx_vminit().
|
||||
*/
|
||||
vmcs_write(VMCS_HOST_CR3, rcr3());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user