git: 39ec056e6dbd - main - vmm: Rework snapshotting of CPU-specific per-vCPU data.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Nov 2022 18:26:26 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=39ec056e6dbd89e26ee21d2928dbd37335de0ebc
commit 39ec056e6dbd89e26ee21d2928dbd37335de0ebc
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-11-18 17:58:41 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-11-18 18:25:35 +0000
vmm: Rework snapshotting of CPU-specific per-vCPU data.
Previously some per-vCPU state was saved in vmmops_snapshot and other
state was saved in vmmops_vcmx_snapshot. Consolidate all per-vCPU
state into the latter routine and rename the hook to the more generic
'vcpu_snapshot'. Note that the CPU-independent per-vCPU data is still
stored in a separate blob as well as the per-vCPU local APIC data.
Reviewed by: corvink, markj
Differential Revision: https://reviews.freebsd.org/D37150
---
sys/amd64/include/vmm.h | 4 +-
sys/amd64/vmm/amd/svm.c | 239 ++++++++++++++++++++++------------------------
sys/amd64/vmm/intel/vmx.c | 87 ++++++++---------
sys/amd64/vmm/vmm.c | 4 +-
4 files changed, 157 insertions(+), 177 deletions(-)
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 37a74f053fb3..f0707a10b804 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -185,7 +185,7 @@ typedef void (*vmi_vmspace_free)(struct vmspace *vmspace);
typedef struct vlapic * (*vmi_vlapic_init)(void *vmi, int vcpu);
typedef void (*vmi_vlapic_cleanup)(void *vmi, struct vlapic *vlapic);
typedef int (*vmi_snapshot_t)(void *vmi, struct vm_snapshot_meta *meta);
-typedef int (*vmi_snapshot_vmcx_t)(void *vmi, struct vm_snapshot_meta *meta,
+typedef int (*vmi_snapshot_vcpu_t)(void *vmi, struct vm_snapshot_meta *meta,
int vcpu);
typedef int (*vmi_restore_tsc_t)(void *vmi, int vcpuid, uint64_t now);
@@ -210,7 +210,7 @@ struct vmm_ops {
/* checkpoint operations */
vmi_snapshot_t snapshot;
- vmi_snapshot_vmcx_t vmcx_snapshot;
+ vmi_snapshot_vcpu_t vcpu_snapshot;
vmi_restore_tsc_t restore_tsc;
};
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index d6502e331278..fca3722ed7f4 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -2428,224 +2428,213 @@ svm_vlapic_cleanup(void *arg, struct vlapic *vlapic)
static int
svm_snapshot(void *arg, struct vm_snapshot_meta *meta)
{
- /* struct svm_softc is AMD's representation for SVM softc */
- struct svm_softc *sc;
- struct svm_vcpu *vcpu;
- int ret;
- uint16_t i, maxcpus;
-
- sc = arg;
-
- KASSERT(sc != NULL, ("%s: arg was NULL", __func__));
-
- maxcpus = vm_get_maxcpus(sc->vm);
- for (i = 0; i < maxcpus; i++) {
- vcpu = &sc->vcpu[i];
-
- /* Snapshot swctx for virtual cpu i */
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rbp, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rbx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rcx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rdx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rdi, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rsi, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r8, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r9, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r10, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r11, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r12, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r13, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r14, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r15, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr0, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr1, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr2, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr3, meta, ret, done);
-
- /* Restore other svm_vcpu struct fields */
-
- /* Restore NEXTRIP field */
- SNAPSHOT_VAR_OR_LEAVE(vcpu->nextrip, meta, ret, done);
-
- /* Restore lastcpu field */
- SNAPSHOT_VAR_OR_LEAVE(vcpu->lastcpu, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->dirty, meta, ret, done);
-
- /* Restore EPTGEN field - EPT is Extended Page Table */
- SNAPSHOT_VAR_OR_LEAVE(vcpu->eptgen, meta, ret, done);
-
- SNAPSHOT_VAR_OR_LEAVE(vcpu->asid.gen, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vcpu->asid.num, meta, ret, done);
-
- /* Set all caches dirty */
- if (meta->op == VM_SNAPSHOT_RESTORE)
- svm_set_dirty(sc, i, 0xffffffff);
- }
-
if (meta->op == VM_SNAPSHOT_RESTORE)
flush_by_asid();
-done:
- return (ret);
+ return (0);
}
static int
-svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpu)
+svm_vcpu_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpuid)
{
struct svm_softc *sc;
+ struct svm_vcpu *vcpu;
int err, running, hostcpu;
sc = (struct svm_softc *)arg;
+ vcpu = &sc->vcpu[vcpuid];
err = 0;
KASSERT(arg != NULL, ("%s: arg was NULL", __func__));
- running = vcpu_is_running(sc->vm, vcpu, &hostcpu);
- if (running && hostcpu !=curcpu) {
- printf("%s: %s%d is running", __func__, vm_name(sc->vm), vcpu);
+ running = vcpu_is_running(sc->vm, vcpuid, &hostcpu);
+ if (running && hostcpu != curcpu) {
+ printf("%s: %s%d is running", __func__, vm_name(sc->vm),
+ vcpuid);
return (EINVAL);
}
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_CR0, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_CR2, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_CR3, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_CR4, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_CR0, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_CR2, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_CR3, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_CR4, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_DR6, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_DR7, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_DR6, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_DR7, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_RAX, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_RAX, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_RSP, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_RIP, meta);
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_RFLAGS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_RSP, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_RIP, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_RFLAGS, meta);
/* Guest segments */
/* ES */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_ES, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_ES, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_ES, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_ES, meta);
/* CS */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_CS, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_CS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_CS, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_CS, meta);
/* SS */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_SS, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_SS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_SS, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_SS, meta);
/* DS */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_DS, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_DS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_DS, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_DS, meta);
/* FS */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_FS, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_FS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_FS, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_FS, meta);
/* GS */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_GS, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_GS, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_GS, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_GS, meta);
/* TR */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_TR, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_TR, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_TR, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_TR, meta);
/* LDTR */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_LDTR, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_LDTR, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_LDTR, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_LDTR, meta);
/* EFER */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_EFER, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_EFER, meta);
/* IDTR and GDTR */
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_IDTR, meta);
- err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_GDTR, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_IDTR, meta);
+ err += vmcb_snapshot_desc(sc, vcpuid, VM_REG_GUEST_GDTR, meta);
/* Specific AMD registers */
- err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_INTR_SHADOW, meta);
+ err += svm_snapshot_reg(sc, vcpuid, VM_REG_GUEST_INTR_SHADOW, meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_CR_INTERCEPT, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_DR_INTERCEPT, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_EXC_INTERCEPT, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_INST1_INTERCEPT, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_INST2_INTERCEPT, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_PAUSE_FILTHRESH, 2), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_PAUSE_FILCNT, 2), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_ASID, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_TLB_CTRL, 4), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_VIRQ, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_EXIT_REASON, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_EXITINFO1, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_EXITINFO2, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_EXITINTINFO, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_NP_ENABLE, 1), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_AVIC_BAR, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_AVIC_PAGE, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_AVIC_LT, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_AVIC_PT, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_CPL, 1), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_STAR, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_LSTAR, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_CSTAR, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_SFMASK, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_KERNELGBASE, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_SYSENTER_CS, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_SYSENTER_ESP, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_SYSENTER_EIP, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_GUEST_PAT, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_DBGCTL, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_BR_FROM, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_BR_TO, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_INT_FROM, 8), meta);
- err += vmcb_snapshot_any(sc, vcpu,
+ err += vmcb_snapshot_any(sc, vcpuid,
VMCB_ACCESS(VMCB_OFF_INT_TO, 8), meta);
+ if (err != 0)
+ goto done;
+ /* Snapshot swctx for virtual cpu */
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rbp, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rbx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rcx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rdx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rdi, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rsi, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r8, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r9, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r10, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r11, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r12, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r13, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r14, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_r15, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr0, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr1, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr2, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr3, meta, err, done);
+
+ /* Restore other svm_vcpu struct fields */
+
+ /* Restore NEXTRIP field */
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->nextrip, meta, err, done);
+
+ /* Restore lastcpu field */
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->lastcpu, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->dirty, meta, err, done);
+
+ /* Restore EPTGEN field - EPT is Extended Page Table */
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->eptgen, meta, err, done);
+
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->asid.gen, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vcpu->asid.num, meta, err, done);
+
+ /* Set all caches dirty */
+ if (meta->op == VM_SNAPSHOT_RESTORE)
+ svm_set_dirty(sc, vcpuid, 0xffffffff);
+done:
return (err);
}
@@ -2679,7 +2668,7 @@ const struct vmm_ops vmm_ops_amd = {
.vlapic_cleanup = svm_vlapic_cleanup,
#ifdef BHYVE_SNAPSHOT
.snapshot = svm_snapshot,
- .vmcx_snapshot = svm_vmcx_snapshot,
+ .vcpu_snapshot = svm_vcpu_snapshot,
.restore_tsc = svm_restore_tsc,
#endif
};
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 8b71ed2e39c1..7ece03a44952 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -4102,67 +4102,29 @@ vmx_vlapic_cleanup(void *arg, struct vlapic *vlapic)
static int
vmx_snapshot(void *arg, struct vm_snapshot_meta *meta)
{
- struct vmx *vmx;
- struct vmx_vcpu *vcpu;
- struct vmxctx *vmxctx;
- int ret;
- uint16_t i, maxcpus;
-
- vmx = arg;
-
- KASSERT(vmx != NULL, ("%s: arg was NULL", __func__));
-
- maxcpus = vm_get_maxcpus(vmx->vm);
- for (i = 0; i < maxcpus; i++) {
- vcpu = &vmx->vcpus[i];
-
- SNAPSHOT_BUF_OR_LEAVE(vcpu->guest_msrs,
- sizeof(vcpu->guest_msrs), meta, ret, done);
-
- vmxctx = &vcpu->ctx;
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rdi, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rsi, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rdx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rcx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r8, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r9, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rax, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rbx, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rbp, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r10, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r11, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r12, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r13, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r14, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r15, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_cr2, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr0, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr1, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr2, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr3, meta, ret, done);
- SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr6, meta, ret, done);
- }
-
-done:
- return (ret);
+ return (0);
}
static int
-vmx_vmcx_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpu)
+vmx_vcpu_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpuid)
{
struct vmcs *vmcs;
struct vmx *vmx;
+ struct vmx_vcpu *vcpu;
+ struct vmxctx *vmxctx;
int err, run, hostcpu;
vmx = (struct vmx *)arg;
err = 0;
KASSERT(arg != NULL, ("%s: arg was NULL", __func__));
- vmcs = vmx->vcpus[vcpu].vmcs;
+ vcpu = &vmx->vcpus[vcpuid];
+ vmcs = vcpu->vmcs;
- run = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
+ run = vcpu_is_running(vmx->vm, vcpuid, &hostcpu);
if (run && hostcpu != curcpu) {
- printf("%s: %s%d is running", __func__, vm_name(vmx->vm), vcpu);
+ printf("%s: %s%d is running", __func__, vm_name(vmx->vm),
+ vcpuid);
return (EINVAL);
}
@@ -4218,7 +4180,36 @@ vmx_vmcx_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpu)
err += vmcs_snapshot_any(vmcs, run, VMCS_GUEST_ACTIVITY, meta);
err += vmcs_snapshot_any(vmcs, run, VMCS_ENTRY_CTLS, meta);
err += vmcs_snapshot_any(vmcs, run, VMCS_EXIT_CTLS, meta);
+ if (err != 0)
+ goto done;
+
+ SNAPSHOT_BUF_OR_LEAVE(vcpu->guest_msrs,
+ sizeof(vcpu->guest_msrs), meta, err, done);
+
+ vmxctx = &vcpu->ctx;
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rdi, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rsi, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rdx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rcx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r8, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r9, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rax, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rbx, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_rbp, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r10, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r11, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r12, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r13, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r14, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_r15, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_cr2, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr0, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr1, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr2, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr3, meta, err, done);
+ SNAPSHOT_VAR_OR_LEAVE(vmxctx->guest_dr6, meta, err, done);
+done:
return (err);
}
@@ -4268,7 +4259,7 @@ const struct vmm_ops vmm_ops_intel = {
.vlapic_cleanup = vmx_vlapic_cleanup,
#ifdef BHYVE_SNAPSHOT
.snapshot = vmx_snapshot,
- .vmcx_snapshot = vmx_vmcx_snapshot,
+ .vcpu_snapshot = vmx_vcpu_snapshot,
.restore_tsc = vmx_restore_tsc,
#endif
};
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index da1db09bdf58..89dedc676610 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -229,7 +229,7 @@ DEFINE_VMMOPS_IFUNC(void, vlapic_cleanup, (void *vmi, struct vlapic *vlapic))
#ifdef BHYVE_SNAPSHOT
DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta
*meta))
-DEFINE_VMMOPS_IFUNC(int, vmcx_snapshot, (void *vmi, struct vm_snapshot_meta
+DEFINE_VMMOPS_IFUNC(int, vcpu_snapshot, (void *vmi, struct vm_snapshot_meta
*meta, int vcpu))
DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vmi, int vcpuid, uint64_t now))
#endif
@@ -2860,7 +2860,7 @@ vm_snapshot_vmcx(struct vm *vm, struct vm_snapshot_meta *meta)
maxcpus = vm_get_maxcpus(vm);
for (i = 0; i < maxcpus; i++) {
- error = vmmops_vmcx_snapshot(vm->cookie, meta, i);
+ error = vmmops_vcpu_snapshot(vm->cookie, meta, i);
if (error != 0) {
printf("%s: failed to snapshot vmcs/vmcb data for "
"vCPU: %d; error: %d\n", __func__, i, error);