diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -185,7 +185,7 @@ 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 @@ /* 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 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -2426,233 +2426,222 @@ 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, VMCB_CACHE_ASID); - svm_set_dirty(sc, i, VMCB_CACHE_IOPM); - svm_set_dirty(sc, i, VMCB_CACHE_I); - svm_set_dirty(sc, i, VMCB_CACHE_TPR); - svm_set_dirty(sc, i, VMCB_CACHE_CR2); - svm_set_dirty(sc, i, VMCB_CACHE_CR); - svm_set_dirty(sc, i, VMCB_CACHE_DT); - svm_set_dirty(sc, i, VMCB_CACHE_SEG); - svm_set_dirty(sc, i, VMCB_CACHE_NP); - } - } - 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 i */ + 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, VMCB_CACHE_ASID); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_IOPM); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_I); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_TPR); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_CR2); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_CR); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_DT); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_SEG); + svm_set_dirty(sc, vcpuid, VMCB_CACHE_NP); + } +done: return (err); } @@ -2686,7 +2675,7 @@ .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 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -4099,67 +4099,29 @@ 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); } @@ -4215,7 +4177,36 @@ 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); } @@ -4265,7 +4256,7 @@ .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 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -229,7 +229,7 @@ #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 @@ -2859,7 +2859,7 @@ 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);