Date: Fri, 5 Sep 2014 03:33:16 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r271152 - projects/bhyve_svm/sys/amd64/vmm/amd Message-ID: <201409050333.s853XGED040153@svn.freebsd.org>
index | next in thread | raw e-mail
Author: neel Date: Fri Sep 5 03:33:16 2014 New Revision: 271152 URL: http://svnweb.freebsd.org/changeset/base/271152 Log: Merge svm_set_vmcb() and svm_init_vmcb() into a single function that is called just once when a vcpu is initialized. Discussed with: Anish Gupta (akgupt3@gmail.com) Modified: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.c projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.h Modified: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c ============================================================================== --- projects/bhyve_svm/sys/amd64/vmm/amd/svm.c Fri Sep 5 02:21:45 2014 (r271151) +++ projects/bhyve_svm/sys/amd64/vmm/amd/svm.c Fri Sep 5 03:33:16 2014 (r271152) @@ -373,29 +373,7 @@ svm_msr_rd_ok(uint8_t *perm_bitmap, uint { return svm_msr_perm(perm_bitmap, msr, true, false); } -/* - * Initialise VCPU. - */ -static int -svm_init_vcpu(struct svm_vcpu *vcpu, vm_paddr_t iopm_pa, vm_paddr_t msrpm_pa, - vm_paddr_t pml4_pa, uint8_t asid) -{ - - vcpu->lastcpu = NOCPU; - vcpu->vmcb_pa = vtophys(&vcpu->vmcb); - - /* - * Initiaise VMCB persistent area of vcpu. - * 1. Permission bitmap for MSR and IO space. - * 2. Nested paging. - * 3. ASID of virtual machine. - */ - if (svm_init_vmcb(&vcpu->vmcb, iopm_pa, msrpm_pa, pml4_pa)) { - return (EIO); - } - - return (0); -} + /* * Initialise a virtual machine. */ @@ -403,8 +381,9 @@ static void * svm_vminit(struct vm *vm, pmap_t pmap) { struct svm_softc *svm_sc; + struct svm_vcpu *vcpu; vm_paddr_t msrpm_pa, iopm_pa, pml4_pa; - int i; + int i, error; if (guest_asid >= max_asid) { ERR("Host support max ASID:%d, can't create more guests.\n", @@ -460,13 +439,15 @@ svm_vminit(struct vm *vm, pmap_t pmap) pml4_pa = svm_sc->nptp; for (i = 0; i < svm_sc->vcpu_cnt; i++) { - if (svm_init_vcpu(svm_get_vcpu(svm_sc, i), iopm_pa, msrpm_pa, - pml4_pa, svm_sc->asid)) { - ERR("SVM couldn't initialise VCPU%d\n", i); + vcpu = svm_get_vcpu(svm_sc, i); + vcpu->lastcpu = NOCPU; + vcpu->vmcb_pa = vtophys(&vcpu->vmcb); + error = svm_init_vmcb(&vcpu->vmcb, iopm_pa, msrpm_pa, pml4_pa, + svm_sc->asid); + if (error) goto cleanup; - } } - + return (svm_sc); cleanup: @@ -1236,8 +1217,6 @@ svm_vmrun(void *arg, int vcpu, register_ break; } - (void)svm_set_vmcb(svm_get_vmcb(svm_sc, vcpu), svm_sc->asid); - svm_inj_interrupts(svm_sc, vcpu, vlapic); /* Launch Virtual Machine. */ Modified: projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.c ============================================================================== --- projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.c Fri Sep 5 02:21:45 2014 (r271151) +++ projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.c Fri Sep 5 03:33:16 2014 (r271152) @@ -52,11 +52,12 @@ __FBSDID("$FreeBSD$"); * Initialize SVM h/w context i.e. the VMCB control and saved state areas. */ int -svm_init_vmcb(struct vmcb *vmcb, uint64_t iopm_base_pa, - uint64_t msrpm_base_pa, uint64_t np_pml4) +svm_init_vmcb(struct vmcb *vmcb, uint64_t iopm_base_pa, uint64_t msrpm_base_pa, + uint64_t np_pml4, uint32_t asid) { struct vmcb_ctrl *ctrl; struct vmcb_state *state; + uint16_t cr_shadow; ctrl = &vmcb->ctrl; state = &vmcb->state; @@ -67,38 +68,6 @@ svm_init_vmcb(struct vmcb *vmcb, uint64_ /* Enable nested paging */ ctrl->np_enable = 1; ctrl->n_cr3 = np_pml4; - - /* 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); - - return (0); -} - -/* - * Set non-persistent fields of VMCB that are cleared by VMEXIT and must - * be set before restarting the guest (e.g. ASID, intercepts etc). - * - * APM2, Section 15.6, VMEXIT - */ -int -svm_set_vmcb(struct vmcb *vmcb, uint8_t asid) -{ - struct vmcb_ctrl *ctrl; - struct vmcb_state *state; - uint16_t cr_shadow; - - ctrl = &vmcb->ctrl; - state = &vmcb->state; /* * Intercept accesses to the control registers that are not shadowed @@ -110,7 +79,7 @@ svm_set_vmcb(struct vmcb *vmcb, uint8_t /* Intercept Machine Check exceptions. */ ctrl->exception = BIT(IDT_MC); - /* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */ + /* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */ ctrl->ctrl1 = VMCB_INTCPT_IO | VMCB_INTCPT_MSR | VMCB_INTCPT_HLT | @@ -123,10 +92,12 @@ svm_set_vmcb(struct vmcb *vmcb, uint8_t VMCB_INTCPT_FERR_FREEZE | VMCB_INTCPT_SHUTDOWN; - /* VMRUN intercept is required, see APM2 */ + /* + * 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; - /* ASID is cleared after every #VMEXIT. */ ctrl->asid = asid; /* @@ -137,10 +108,23 @@ svm_set_vmcb(struct vmcb *vmcb, uint8_t */ ctrl->v_intr_masking = 1; - /* Enable Last Branch Record aka LBR for debugging */ + /* 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); + return (0); } Modified: projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.h ============================================================================== --- projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.h Fri Sep 5 02:21:45 2014 (r271151) +++ projects/bhyve_svm/sys/amd64/vmm/amd/vmcb.h Fri Sep 5 03:33:16 2014 (r271152) @@ -278,8 +278,7 @@ CTASSERT(sizeof(struct vmcb) == PAGE_SIZ CTASSERT(offsetof(struct vmcb, state) == 0x400); int svm_init_vmcb(struct vmcb *vmcb, uint64_t iopm_base_pa, - uint64_t msrpm_base_pa, uint64_t np_pml4); -int svm_set_vmcb(struct vmcb *vmcb, uint8_t asid); + uint64_t msrpm_base_pa, uint64_t np_pml4, uint32_t asid); 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);help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409050333.s853XGED040153>
