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