svn commit: r271152 - projects/bhyve_svm/sys/amd64/vmm/amd
Neel Natu
neel at FreeBSD.org
Fri Sep 5 03:33:17 UTC 2014
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 at 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);
More information about the svn-src-projects
mailing list