diff options
author | neel <neel@FreeBSD.org> | 2014-09-10 02:35:19 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2014-09-10 02:35:19 +0000 |
commit | 3c61bfaac64de553182188d289fb9befc7fc6a57 (patch) | |
tree | 1807ec0e7b10c29e3925a5e6bc62ffc874860074 /sys/amd64/vmm | |
parent | bbc4ff544fe5975fbab29628145346683b2d7a3a (diff) | |
download | FreeBSD-src-3c61bfaac64de553182188d289fb9befc7fc6a57.zip FreeBSD-src-3c61bfaac64de553182188d289fb9befc7fc6a57.tar.gz |
Move the VMCB initialization into svm.c in preparation for changes to the
interrupt injection logic.
Discussed with: Anish Gupta (akgupt3@gmail.com)
Diffstat (limited to 'sys/amd64/vmm')
-rw-r--r-- | sys/amd64/vmm/amd/svm.c | 80 | ||||
-rw-r--r-- | sys/amd64/vmm/amd/vmcb.c | 81 | ||||
-rw-r--r-- | sys/amd64/vmm/amd/vmcb.h | 2 |
3 files changed, 79 insertions, 84 deletions
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 175a907..6946d5c 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -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); } diff --git a/sys/amd64/vmm/amd/vmcb.c b/sys/amd64/vmm/amd/vmcb.c index 9e25e9d..6c3555e 100644 --- a/sys/amd64/vmm/amd/vmcb.c +++ b/sys/amd64/vmm/amd/vmcb.c @@ -49,87 +49,6 @@ __FBSDID("$FreeBSD$"); */ /* - * 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. */ int diff --git a/sys/amd64/vmm/amd/vmcb.h b/sys/amd64/vmm/amd/vmcb.h index c8a23c9..fa7d12f 100644 --- a/sys/amd64/vmm/amd/vmcb.h +++ b/sys/amd64/vmm/amd/vmcb.h @@ -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); |