The branch stable/13 has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f5bc0f74668155dee515614ae2e2b8e1e3d1abaa

commit f5bc0f74668155dee515614ae2e2b8e1e3d1abaa
Author:     John Baldwin <[email protected]>
AuthorDate: 2022-11-18 17:58:41 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2023-01-26 21:44:33 +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
    
    (cherry picked from commit 39ec056e6dbd89e26ee21d2928dbd37335de0ebc)
---
 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 a957ecb0f852..62456fe9d12d 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 9b285df04092..0b1df029274e 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
@@ -2858,7 +2858,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);

Reply via email to