The branch stable/13 has been updated by jhb:

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

commit be9a57eda10653ff625dccd4b867209d53434a1f
Author:     Mihai Burcea <[email protected]>
AuthorDate: 2022-06-30 23:11:17 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2023-01-26 19:29:41 +0000

    vmm: Fix snapshots for AMD CPUs
    
    This patch fixes the AMD implementation for snapshotting.  It removes
    unnecessary vmcb fields that should not be saved and duplicates.
    
    Reviewed by:    jhb
    Differential Revision: https://reviews.freebsd.org/D33431
    
    (cherry picked from commit 9aa02d5120ab02bcbbc16fddb63e575df4ed6f61)
---
 sys/amd64/vmm/amd/svm.c  | 146 +++++++++++++++--------------------------------
 sys/amd64/vmm/amd/vmcb.c |   1 +
 sys/amd64/vmm/amd/vmcb.h |  15 +++++
 3 files changed, 62 insertions(+), 100 deletions(-)

diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 8fbe0817fc8e..4195cc5bd049 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -2422,8 +2422,6 @@ 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;
-       struct vmcb *vmcb;
-       uint64_t val;
        int i;
        int ret;
 
@@ -2431,78 +2429,8 @@ svm_snapshot(void *arg, struct vm_snapshot_meta *meta)
 
        KASSERT(sc != NULL, ("%s: arg was NULL", __func__));
 
-       SNAPSHOT_VAR_OR_LEAVE(sc->nptp, meta, ret, done);
-
        for (i = 0; i < VM_MAXCPU; i++) {
                vcpu = &sc->vcpu[i];
-               vmcb = &vcpu->vmcb;
-
-               /* VMCB fields for virtual cpu i */
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->ctrl.v_tpr, meta, ret, done);
-               val = vmcb->ctrl.v_tpr;
-               SNAPSHOT_VAR_OR_LEAVE(val, meta, ret, done);
-               vmcb->ctrl.v_tpr = val;
-
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->ctrl.asid, meta, ret, done);
-               val = vmcb->ctrl.np_enable;
-               SNAPSHOT_VAR_OR_LEAVE(val, meta, ret, done);
-               vmcb->ctrl.np_enable = val;
-
-               val = vmcb->ctrl.intr_shadow;
-               SNAPSHOT_VAR_OR_LEAVE(val, meta, ret, done);
-               vmcb->ctrl.intr_shadow = val;
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->ctrl.tlb_ctrl, meta, ret, done);
-
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad1,
-                                     sizeof(vmcb->state.pad1),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cpl, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad2,
-                                     sizeof(vmcb->state.pad2),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.efer, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad3,
-                                     sizeof(vmcb->state.pad3),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cr4, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cr3, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cr0, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.dr7, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.dr6, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.rflags, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.rip, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad4,
-                                     sizeof(vmcb->state.pad4),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.rsp, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad5,
-                                     sizeof(vmcb->state.pad5),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.rax, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.star, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.lstar, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cstar, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.sfmask, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.kernelgsbase,
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.sysenter_cs, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.sysenter_esp,
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.sysenter_eip,
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.cr2, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad6,
-                                     sizeof(vmcb->state.pad6),
-                                     meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.g_pat, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.dbgctl, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.br_from, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.br_to, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.int_from, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vmcb->state.int_to, meta, ret, done);
-               SNAPSHOT_BUF_OR_LEAVE(vmcb->state.pad7,
-                                     sizeof(vmcb->state.pad7),
-                                     meta, ret, done);
 
                /* Snapshot swctx for virtual cpu i */
                SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_rbp, meta, ret, done);
@@ -2524,15 +2452,6 @@ svm_snapshot(void *arg, struct vm_snapshot_meta *meta)
                SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr2, meta, ret, done);
                SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.sctx_dr3, meta, ret, done);
 
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr0, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr1, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr2, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr3, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr6, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_dr7, meta, ret, done);
-               SNAPSHOT_VAR_OR_LEAVE(vcpu->swctx.host_debugctl, meta, ret,
-                                     done);
-
                /* Restore other svm_vcpu struct fields */
 
                /* Restore NEXTRIP field */
@@ -2542,7 +2461,7 @@ svm_snapshot(void *arg, struct vm_snapshot_meta *meta)
                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 Tabel */
+               /* 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);
@@ -2591,6 +2510,7 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta 
*meta, int vcpu)
        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, vcpu, VM_REG_GUEST_DR6, meta);
        err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_DR7, meta);
 
        err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_RAX, meta);
@@ -2640,15 +2560,7 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta 
*meta, int vcpu)
        err += vmcb_snapshot_desc(sc, vcpu, VM_REG_GUEST_GDTR, meta);
 
        /* Specific AMD registers */
-       err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_SYSENTER_CS, 8), meta);
-       err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_SYSENTER_ESP, 8), meta);
-       err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_SYSENTER_EIP, 8), meta);
-
-       err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_NPT_BASE, 8), meta);
+       err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_INTR_SHADOW, meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
                                VMCB_ACCESS(VMCB_OFF_CR_INTERCEPT, 4), meta);
@@ -2661,9 +2573,22 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta 
*meta, int vcpu)
        err += vmcb_snapshot_any(sc, vcpu,
                                VMCB_ACCESS(VMCB_OFF_INST2_INTERCEPT, 4), meta);
 
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_PAUSE_FILTHRESH, 2), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_PAUSE_FILCNT, 2), meta);
+
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_ASID, 4), meta);
+
        err += vmcb_snapshot_any(sc, vcpu,
                                VMCB_ACCESS(VMCB_OFF_TLB_CTRL, 4), meta);
 
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_VIRQ, 8), meta);
+
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_EXIT_REASON, 8), meta);
        err += vmcb_snapshot_any(sc, vcpu,
                                VMCB_ACCESS(VMCB_OFF_EXITINFO1, 8), meta);
        err += vmcb_snapshot_any(sc, vcpu,
@@ -2672,10 +2597,7 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta 
*meta, int vcpu)
                                VMCB_ACCESS(VMCB_OFF_EXITINTINFO, 8), meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_VIRQ, 8), meta);
-
-       err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_GUEST_PAT, 8), meta);
+                               VMCB_ACCESS(VMCB_OFF_NP_ENABLE, 1), meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
                                VMCB_ACCESS(VMCB_OFF_AVIC_BAR, 8), meta);
@@ -2687,17 +2609,41 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta 
*meta, int vcpu)
                                VMCB_ACCESS(VMCB_OFF_AVIC_PT, 8), meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_IO_PERM, 8), meta);
+                               VMCB_ACCESS(VMCB_OFF_CPL, 1), meta);
+
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_STAR, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_LSTAR, 8), meta);
        err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_MSR_PERM, 8), meta);
+                               VMCB_ACCESS(VMCB_OFF_CSTAR, 8), meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_ASID, 4), meta);
+                               VMCB_ACCESS(VMCB_OFF_SFMASK, 8), meta);
 
        err += vmcb_snapshot_any(sc, vcpu,
-                               VMCB_ACCESS(VMCB_OFF_EXIT_REASON, 8), meta);
+                               VMCB_ACCESS(VMCB_OFF_KERNELGBASE, 8), meta);
 
-       err += svm_snapshot_reg(sc, vcpu, VM_REG_GUEST_INTR_SHADOW, meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_SYSENTER_CS, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_SYSENTER_ESP, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_SYSENTER_EIP, 8), meta);
+
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_GUEST_PAT, 8), meta);
+
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_DBGCTL, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_BR_FROM, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_BR_TO, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_INT_FROM, 8), meta);
+       err += vmcb_snapshot_any(sc, vcpu,
+                               VMCB_ACCESS(VMCB_OFF_INT_TO, 8), meta);
 
        return (err);
 }
diff --git a/sys/amd64/vmm/amd/vmcb.c b/sys/amd64/vmm/amd/vmcb.c
index bf4a6d004bcd..0341e4e6c07c 100644
--- a/sys/amd64/vmm/amd/vmcb.c
+++ b/sys/amd64/vmm/amd/vmcb.c
@@ -139,6 +139,7 @@ vmcb_access(struct svm_softc *softc, int vcpu, int write, 
int ident,
        case 8:
        case 4:
        case 2:
+       case 1:
                if (write)
                        memcpy(ptr + off, val, bytes);
                else
diff --git a/sys/amd64/vmm/amd/vmcb.h b/sys/amd64/vmm/amd/vmcb.h
index 847e1f6ad476..084f4465cb49 100644
--- a/sys/amd64/vmm/amd/vmcb.h
+++ b/sys/amd64/vmm/amd/vmcb.h
@@ -187,6 +187,8 @@
 #define        VMCB_OFF_EXC_INTERCEPT          VMCB_OFF_CTRL(0x8)
 #define        VMCB_OFF_INST1_INTERCEPT        VMCB_OFF_CTRL(0xC)
 #define        VMCB_OFF_INST2_INTERCEPT        VMCB_OFF_CTRL(0x10)
+#define        VMCB_OFF_PAUSE_FILTHRESH        VMCB_OFF_CTRL(0x3C)
+#define        VMCB_OFF_PAUSE_FILCNT           VMCB_OFF_CTRL(0x3E)
 #define        VMCB_OFF_IO_PERM                VMCB_OFF_CTRL(0x40)
 #define        VMCB_OFF_MSR_PERM               VMCB_OFF_CTRL(0x48)
 #define        VMCB_OFF_TSC_OFFSET             VMCB_OFF_CTRL(0x50)
@@ -197,15 +199,28 @@
 #define        VMCB_OFF_EXITINFO1              VMCB_OFF_CTRL(0x78)
 #define        VMCB_OFF_EXITINFO2              VMCB_OFF_CTRL(0x80)
 #define        VMCB_OFF_EXITINTINFO            VMCB_OFF_CTRL(0x88)
+#define        VMCB_OFF_NP_ENABLE              VMCB_OFF_CTRL(0x90)
 #define        VMCB_OFF_AVIC_BAR               VMCB_OFF_CTRL(0x98)
 #define        VMCB_OFF_NPT_BASE               VMCB_OFF_CTRL(0xB0)
 #define        VMCB_OFF_AVIC_PAGE              VMCB_OFF_CTRL(0xE0)
 #define        VMCB_OFF_AVIC_LT                VMCB_OFF_CTRL(0xF0)
 #define        VMCB_OFF_AVIC_PT                VMCB_OFF_CTRL(0xF8)
+
+#define        VMCB_OFF_CPL                    VMCB_OFF_STATE(0xCB)
+#define        VMCB_OFF_STAR                   VMCB_OFF_STATE(0x200)
+#define        VMCB_OFF_LSTAR                  VMCB_OFF_STATE(0x208)
+#define        VMCB_OFF_CSTAR                  VMCB_OFF_STATE(0x210)
+#define        VMCB_OFF_SFMASK                 VMCB_OFF_STATE(0x218)
+#define        VMCB_OFF_KERNELGBASE            VMCB_OFF_STATE(0x220)
 #define        VMCB_OFF_SYSENTER_CS            VMCB_OFF_STATE(0x228)
 #define        VMCB_OFF_SYSENTER_ESP           VMCB_OFF_STATE(0x230)
 #define        VMCB_OFF_SYSENTER_EIP           VMCB_OFF_STATE(0x238)
 #define        VMCB_OFF_GUEST_PAT              VMCB_OFF_STATE(0x268)
+#define        VMCB_OFF_DBGCTL                 VMCB_OFF_STATE(0x270)
+#define        VMCB_OFF_BR_FROM                VMCB_OFF_STATE(0x278)
+#define        VMCB_OFF_BR_TO                  VMCB_OFF_STATE(0x280)
+#define        VMCB_OFF_INT_FROM               VMCB_OFF_STATE(0x288)
+#define        VMCB_OFF_INT_TO                 VMCB_OFF_STATE(0x290)
 
 /*
  * Encode the VMCB offset and bytes that we want to read from VMCB.

Reply via email to