Move the VMCB initialization into svm.c in preparation for changes to the
interrupt injection logic. Discussed with: Anish Gupta (akgupt3@gmail.com)
This commit is contained in:
parent
840b1a2760
commit
e5397c9fdd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/bhyve_svm/; revision=271346
@ -394,6 +394,84 @@ vcpu_set_dirty(struct svm_softc *sc, int vcpu, uint32_t dirtybits)
|
||||
vcpustate->dirty |= dirtybits;
|
||||
}
|
||||
|
||||
static void
|
||||
vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa,
|
||||
uint64_t msrpm_base_pa, uint64_t np_pml4)
|
||||
{
|
||||
struct vmcb_ctrl *ctrl;
|
||||
struct vmcb_state *state;
|
||||
uint16_t cr_shadow;
|
||||
|
||||
ctrl = svm_get_vmcb_ctrl(sc, vcpu);
|
||||
state = svm_get_vmcb_state(sc, vcpu);
|
||||
|
||||
ctrl->iopm_base_pa = iopm_base_pa;
|
||||
ctrl->msrpm_base_pa = msrpm_base_pa;
|
||||
|
||||
/* Enable nested paging */
|
||||
ctrl->np_enable = 1;
|
||||
ctrl->n_cr3 = np_pml4;
|
||||
|
||||
/*
|
||||
* Intercept accesses to the control registers that are not shadowed
|
||||
* in the VMCB - i.e. all except cr0, cr2, cr3, cr4 and cr8.
|
||||
*/
|
||||
cr_shadow = BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(8);
|
||||
ctrl->cr_write = ctrl->cr_read = ~cr_shadow;
|
||||
|
||||
/* Intercept Machine Check exceptions. */
|
||||
ctrl->exception = BIT(IDT_MC);
|
||||
|
||||
/* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */
|
||||
ctrl->ctrl1 = VMCB_INTCPT_IO |
|
||||
VMCB_INTCPT_MSR |
|
||||
VMCB_INTCPT_HLT |
|
||||
VMCB_INTCPT_CPUID |
|
||||
VMCB_INTCPT_INTR |
|
||||
VMCB_INTCPT_VINTR |
|
||||
VMCB_INTCPT_INIT |
|
||||
VMCB_INTCPT_NMI |
|
||||
VMCB_INTCPT_SMI |
|
||||
VMCB_INTCPT_FERR_FREEZE |
|
||||
VMCB_INTCPT_SHUTDOWN;
|
||||
|
||||
/*
|
||||
* From section "Canonicalization and Consistency Checks" in APMv2
|
||||
* the VMRUN intercept bit must be set to pass the consistency check.
|
||||
*/
|
||||
ctrl->ctrl2 = VMCB_INTCPT_VMRUN;
|
||||
|
||||
/*
|
||||
* The ASID will be set to a non-zero value just before VMRUN.
|
||||
*/
|
||||
ctrl->asid = 0;
|
||||
|
||||
/*
|
||||
* Section 15.21.1, Interrupt Masking in EFLAGS
|
||||
* Section 15.21.2, Virtualizing APIC.TPR
|
||||
*
|
||||
* This must be set for %rflag and %cr8 isolation of guest and host.
|
||||
*/
|
||||
ctrl->v_intr_masking = 1;
|
||||
|
||||
/* Enable Last Branch Record aka LBR for debugging */
|
||||
ctrl->lbr_virt_en = 1;
|
||||
state->dbgctl = BIT(0);
|
||||
|
||||
/* EFER_SVM must always be set when the guest is executing */
|
||||
state->efer = EFER_SVM;
|
||||
|
||||
/* Set up the PAT to power-on state */
|
||||
state->g_pat = PAT_VALUE(0, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(1, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(2, PAT_UNCACHED) |
|
||||
PAT_VALUE(3, PAT_UNCACHEABLE) |
|
||||
PAT_VALUE(4, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(5, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(6, PAT_UNCACHED) |
|
||||
PAT_VALUE(7, PAT_UNCACHEABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a virtual machine.
|
||||
*/
|
||||
@ -452,7 +530,7 @@ svm_vminit(struct vm *vm, pmap_t pmap)
|
||||
vcpu = svm_get_vcpu(svm_sc, i);
|
||||
vcpu->lastcpu = NOCPU;
|
||||
vcpu->vmcb_pa = vtophys(&vcpu->vmcb);
|
||||
svm_init_vmcb(&vcpu->vmcb, iopm_pa, msrpm_pa, pml4_pa);
|
||||
vmcb_init(svm_sc, i, iopm_pa, msrpm_pa, pml4_pa);
|
||||
}
|
||||
return (svm_sc);
|
||||
}
|
||||
|
@ -48,87 +48,6 @@ __FBSDID("$FreeBSD$");
|
||||
* - guest processor state (e.g. general purpose registers)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize SVM h/w context i.e. the VMCB control and saved state areas.
|
||||
*/
|
||||
void
|
||||
svm_init_vmcb(struct vmcb *vmcb, uint64_t iopm_base_pa, uint64_t msrpm_base_pa,
|
||||
uint64_t np_pml4)
|
||||
{
|
||||
struct vmcb_ctrl *ctrl;
|
||||
struct vmcb_state *state;
|
||||
uint16_t cr_shadow;
|
||||
|
||||
ctrl = &vmcb->ctrl;
|
||||
state = &vmcb->state;
|
||||
|
||||
ctrl->iopm_base_pa = iopm_base_pa;
|
||||
ctrl->msrpm_base_pa = msrpm_base_pa;
|
||||
|
||||
/* Enable nested paging */
|
||||
ctrl->np_enable = 1;
|
||||
ctrl->n_cr3 = np_pml4;
|
||||
|
||||
/*
|
||||
* Intercept accesses to the control registers that are not shadowed
|
||||
* in the VMCB - i.e. all except cr0, cr2, cr3, cr4 and cr8.
|
||||
*/
|
||||
cr_shadow = BIT(0) | BIT(2) | BIT(3) | BIT(4) | BIT(8);
|
||||
ctrl->cr_write = ctrl->cr_read = ~cr_shadow;
|
||||
|
||||
/* Intercept Machine Check exceptions. */
|
||||
ctrl->exception = BIT(IDT_MC);
|
||||
|
||||
/* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */
|
||||
ctrl->ctrl1 = VMCB_INTCPT_IO |
|
||||
VMCB_INTCPT_MSR |
|
||||
VMCB_INTCPT_HLT |
|
||||
VMCB_INTCPT_CPUID |
|
||||
VMCB_INTCPT_INTR |
|
||||
VMCB_INTCPT_VINTR |
|
||||
VMCB_INTCPT_INIT |
|
||||
VMCB_INTCPT_NMI |
|
||||
VMCB_INTCPT_SMI |
|
||||
VMCB_INTCPT_FERR_FREEZE |
|
||||
VMCB_INTCPT_SHUTDOWN;
|
||||
|
||||
/*
|
||||
* From section "Canonicalization and Consistency Checks" in APMv2
|
||||
* the VMRUN intercept bit must be set to pass the consistency check.
|
||||
*/
|
||||
ctrl->ctrl2 = VMCB_INTCPT_VMRUN;
|
||||
|
||||
/*
|
||||
* The ASID will be set to a non-zero value just before VMRUN.
|
||||
*/
|
||||
ctrl->asid = 0;
|
||||
|
||||
/*
|
||||
* Section 15.21.1, Interrupt Masking in EFLAGS
|
||||
* Section 15.21.2, Virtualizing APIC.TPR
|
||||
*
|
||||
* This must be set for %rflag and %cr8 isolation of guest and host.
|
||||
*/
|
||||
ctrl->v_intr_masking = 1;
|
||||
|
||||
/* Enable Last Branch Record aka LBR for debugging */
|
||||
ctrl->lbr_virt_en = 1;
|
||||
state->dbgctl = BIT(0);
|
||||
|
||||
/* EFER_SVM must always be set when the guest is executing */
|
||||
state->efer = EFER_SVM;
|
||||
|
||||
/* Set up the PAT to power-on state */
|
||||
state->g_pat = PAT_VALUE(0, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(1, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(2, PAT_UNCACHED) |
|
||||
PAT_VALUE(3, PAT_UNCACHEABLE) |
|
||||
PAT_VALUE(4, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(5, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(6, PAT_UNCACHED) |
|
||||
PAT_VALUE(7, PAT_UNCACHEABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from segment selector, control and general purpose register of VMCB.
|
||||
*/
|
||||
|
@ -277,8 +277,6 @@ struct vmcb {
|
||||
CTASSERT(sizeof(struct vmcb) == PAGE_SIZE);
|
||||
CTASSERT(offsetof(struct vmcb, state) == 0x400);
|
||||
|
||||
void svm_init_vmcb(struct vmcb *vmcb, uint64_t iopm_base_pa,
|
||||
uint64_t msrpm_base_pa, uint64_t np_pml4);
|
||||
int vmcb_read(struct vmcb *vmcb, int ident, uint64_t *retval);
|
||||
int vmcb_write(struct vmcb *vmcb, int ident, uint64_t val);
|
||||
struct vmcb_segment *vmcb_seg(struct vmcb *vmcb, int type);
|
||||
|
Loading…
Reference in New Issue
Block a user