summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-09-10 02:35:19 +0000
committerneel <neel@FreeBSD.org>2014-09-10 02:35:19 +0000
commit3c61bfaac64de553182188d289fb9befc7fc6a57 (patch)
tree1807ec0e7b10c29e3925a5e6bc62ffc874860074 /sys/amd64/vmm
parentbbc4ff544fe5975fbab29628145346683b2d7a3a (diff)
downloadFreeBSD-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.c80
-rw-r--r--sys/amd64/vmm/amd/vmcb.c81
-rw-r--r--sys/amd64/vmm/amd/vmcb.h2
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);
OpenPOWER on IntegriCloud