Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/nvmm/x86 Optimize: don't keep a full copy of the gue...



details:   https://anonhg.NetBSD.org/src/rev/4126d9fdd368
branches:  trunk
changeset: 447364:4126d9fdd368
user:      maxv <maxv%NetBSD.org@localhost>
date:      Tue Jan 08 14:43:18 2019 +0000

description:
Optimize: don't keep a full copy of the guest state, rather take only what
is needed. This avoids expensive memcpy's.

Also flush the V_TPR as part of the CR-state, because there is CR8 in it.

diffstat:

 sys/dev/nvmm/x86/nvmm_x86_svm.c |  332 ++++++++++++++++++---------------------
 1 files changed, 154 insertions(+), 178 deletions(-)

diffs (truncated from 669 to 300 lines):

diff -r 887c00dd09ed -r 4126d9fdd368 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Tue Jan 08 11:36:10 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Tue Jan 08 14:43:18 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.12 2019/01/07 14:08:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.13 2019/01/08 14:43:18 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -499,9 +499,6 @@
 };
 
 struct svm_cpudata {
-       /* x64-specific */
-       struct nvmm_x64_state state;
-
        /* General */
        bool shared_asid;
        bool tlb_want_flush;
@@ -519,7 +516,7 @@
        paddr_t msrbm_pa;
 
        /* Host state */
-       uint64_t xcr0;
+       uint64_t hxcr0;
        uint64_t star;
        uint64_t lstar;
        uint64_t cstar;
@@ -533,6 +530,9 @@
        bool nmi_window_exit;
 
        /* Guest state */
+       uint64_t gxcr0;
+       uint64_t gprs[NVMM_X64_NGPR];
+       uint64_t drs[NVMM_X64_NDR];
        uint64_t tsc_offset;
        struct xsave_header gfpu __aligned(16);
 };
@@ -564,7 +564,8 @@
        }
        if (flags & NVMM_X64_STATE_CRS) {
                vmcb->ctrl.vmcb_clean &=
-                   ~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2);
+                   ~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_CR2 |
+                     VMCB_CTRL_VMCB_CLEAN_TPR);
        }
        if (flags & NVMM_X64_STATE_DRS) {
                vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_DR;
@@ -755,12 +756,11 @@
 svm_inkernel_handle_cpuid(struct nvmm_cpu *vcpu, uint64_t eax, uint64_t ecx)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
 
        switch (eax) {
        case 0x00000001: /* APIC number in RBX. The rest is tunable. */
-               state->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
-               state->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= ~CPUID_LOCAL_APIC_ID;
+               cpudata->gprs[NVMM_X64_GPR_RBX] |= __SHIFTIN(vcpu->cpuid,
                    CPUID_LOCAL_APIC_ID);
                break;
        case 0x0000000D: /* FPU description. Not tunable. */
@@ -768,22 +768,22 @@
                        break;
                }
                cpudata->vmcb->state.rax = svm_xcr0_mask & 0xFFFFFFFF;
-               if (state->crs[NVMM_X64_CR_XCR0] & XCR0_SSE) {
-                       state->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
+               if (cpudata->gxcr0 & XCR0_SSE) {
+                       cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct fxsave);
                } else {
-                       state->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
+                       cpudata->gprs[NVMM_X64_GPR_RBX] = sizeof(struct save87);
                }
-               state->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
-               state->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
-               state->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
+               cpudata->gprs[NVMM_X64_GPR_RBX] += 64; /* XSAVE header */
+               cpudata->gprs[NVMM_X64_GPR_RCX] = sizeof(struct fxsave);
+               cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
                break;
        case 0x40000000:
-               memcpy(&state->gprs[NVMM_X64_GPR_RBX], "___ ", 4);
-               memcpy(&state->gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
-               memcpy(&state->gprs[NVMM_X64_GPR_RDX], " ___", 4);
+               memcpy(&cpudata->gprs[NVMM_X64_GPR_RBX], "___ ", 4);
+               memcpy(&cpudata->gprs[NVMM_X64_GPR_RCX], "NVMM", 4);
+               memcpy(&cpudata->gprs[NVMM_X64_GPR_RDX], " ___", 4);
                break;
        case 0x80000001: /* No SVM in ECX. The rest is tunable. */
-               state->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
                break;
        default:
                break;
@@ -796,20 +796,19 @@
 {
        struct svm_machdata *machdata = mach->machdata;
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
        struct nvmm_x86_conf_cpuid *cpuid;
        uint64_t eax, ecx;
        u_int descs[4];
        size_t i;
 
        eax = cpudata->vmcb->state.rax;
-       ecx = state->gprs[NVMM_X64_GPR_RCX];
+       ecx = cpudata->gprs[NVMM_X64_GPR_RCX];
        x86_cpuid2(eax, ecx, descs);
 
        cpudata->vmcb->state.rax = descs[0];
-       state->gprs[NVMM_X64_GPR_RBX] = descs[1];
-       state->gprs[NVMM_X64_GPR_RCX] = descs[2];
-       state->gprs[NVMM_X64_GPR_RDX] = descs[3];
+       cpudata->gprs[NVMM_X64_GPR_RBX] = descs[1];
+       cpudata->gprs[NVMM_X64_GPR_RCX] = descs[2];
+       cpudata->gprs[NVMM_X64_GPR_RDX] = descs[3];
 
        for (i = 0; i < SVM_NCPUIDS; i++) {
                cpuid = &machdata->cpuid[i];
@@ -822,15 +821,15 @@
 
                /* del */
                cpudata->vmcb->state.rax &= ~cpuid->del.eax;
-               state->gprs[NVMM_X64_GPR_RBX] &= ~cpuid->del.ebx;
-               state->gprs[NVMM_X64_GPR_RCX] &= ~cpuid->del.ecx;
-               state->gprs[NVMM_X64_GPR_RDX] &= ~cpuid->del.edx;
+               cpudata->gprs[NVMM_X64_GPR_RBX] &= ~cpuid->del.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] &= ~cpuid->del.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] &= ~cpuid->del.edx;
 
                /* set */
                cpudata->vmcb->state.rax |= cpuid->set.eax;
-               state->gprs[NVMM_X64_GPR_RBX] |= cpuid->set.ebx;
-               state->gprs[NVMM_X64_GPR_RCX] |= cpuid->set.ecx;
-               state->gprs[NVMM_X64_GPR_RDX] |= cpuid->set.edx;
+               cpudata->gprs[NVMM_X64_GPR_RBX] |= cpuid->set.ebx;
+               cpudata->gprs[NVMM_X64_GPR_RCX] |= cpuid->set.ecx;
+               cpudata->gprs[NVMM_X64_GPR_RDX] |= cpuid->set.edx;
 
                break;
        }
@@ -936,7 +935,6 @@
     struct nvmm_exit *exit)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
        uint64_t val;
        size_t i;
 
@@ -945,13 +943,13 @@
                if (exit->u.msr.msr == MSR_CR_PAT) {
                        val = cpudata->vmcb->state.g_pat;
                        cpudata->vmcb->state.rax = (val & 0xFFFFFFFF);
-                       state->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
                        goto handled;
                }
                if (exit->u.msr.msr == MSR_NB_CFG) {
                        val = NB_CFG_INITAPICCPUIDLO;
                        cpudata->vmcb->state.rax = (val & 0xFFFFFFFF);
-                       state->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
                        goto handled;
                }
                for (i = 0; i < __arraycount(msr_ignore_list); i++) {
@@ -959,7 +957,7 @@
                                continue;
                        val = 0;
                        cpudata->vmcb->state.rax = (val & 0xFFFFFFFF);
-                       state->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
+                       cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
                        goto handled;
                }
                break;
@@ -1000,7 +998,6 @@
     struct nvmm_exit *exit)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
        uint64_t info = cpudata->vmcb->ctrl.exitinfo1;
 
        if (info == 0) {
@@ -1009,11 +1006,11 @@
                exit->u.msr.type = NVMM_EXIT_MSR_WRMSR;
        }
 
-       exit->u.msr.msr = state->gprs[NVMM_X64_GPR_RCX];
+       exit->u.msr.msr = cpudata->gprs[NVMM_X64_GPR_RCX];
 
        if (info == 1) {
                uint64_t rdx, rax;
-               rdx = state->gprs[NVMM_X64_GPR_RDX];
+               rdx = cpudata->gprs[NVMM_X64_GPR_RDX];
                rax = cpudata->vmcb->state.rax;
                exit->u.msr.val = (rdx << 32) | (rax & 0xFFFFFFFF);
        } else {
@@ -1062,16 +1059,15 @@
     struct nvmm_exit *exit)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
        struct vmcb *vmcb = cpudata->vmcb;
        uint64_t val;
 
        exit->reason = NVMM_EXIT_NONE;
 
-       val = (state->gprs[NVMM_X64_GPR_RDX] << 32) |
+       val = (cpudata->gprs[NVMM_X64_GPR_RDX] << 32) |
            (vmcb->state.rax & 0xFFFFFFFF);
 
-       if (__predict_false(state->gprs[NVMM_X64_GPR_RCX] != 0)) {
+       if (__predict_false(cpudata->gprs[NVMM_X64_GPR_RCX] != 0)) {
                goto error;
        } else if (__predict_false(vmcb->state.cpl != 0)) {
                goto error;
@@ -1081,7 +1077,7 @@
                goto error;
        }
 
-       state->crs[NVMM_X64_CR_XCR0] = val;
+       cpudata->gxcr0 = val;
 
        cpudata->vmcb->state.rip = cpudata->vmcb->ctrl.nrip;
        return;
@@ -1096,8 +1092,8 @@
        struct svm_cpudata *cpudata = vcpu->cpudata;
 
        if (x86_xsave_features != 0) {
-               cpudata->xcr0 = rdxcr(0);
-               wrxcr(0, cpudata->state.crs[NVMM_X64_CR_XCR0]);
+               cpudata->hxcr0 = rdxcr(0);
+               wrxcr(0, cpudata->gxcr0);
        }
 
        cpudata->ts_set = (rcr0() & CR0_TS) != 0;
@@ -1119,8 +1115,8 @@
        }
 
        if (x86_xsave_features != 0) {
-               cpudata->state.crs[NVMM_X64_CR_XCR0] = rdxcr(0);
-               wrxcr(0, cpudata->xcr0);
+               cpudata->gxcr0 = rdxcr(0);
+               wrxcr(0, cpudata->hxcr0);
        }
 }
 
@@ -1128,26 +1124,24 @@
 svm_vcpu_guest_dbregs_enter(struct nvmm_cpu *vcpu)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
 
        x86_dbregs_save(curlwp);
 
-       ldr0(state->drs[NVMM_X64_DR_DR0]);
-       ldr1(state->drs[NVMM_X64_DR_DR1]);
-       ldr2(state->drs[NVMM_X64_DR_DR2]);
-       ldr3(state->drs[NVMM_X64_DR_DR3]);
+       ldr0(cpudata->drs[NVMM_X64_DR_DR0]);
+       ldr1(cpudata->drs[NVMM_X64_DR_DR1]);
+       ldr2(cpudata->drs[NVMM_X64_DR_DR2]);
+       ldr3(cpudata->drs[NVMM_X64_DR_DR3]);
 }
 
 static void
 svm_vcpu_guest_dbregs_leave(struct nvmm_cpu *vcpu)
 {
        struct svm_cpudata *cpudata = vcpu->cpudata;
-       struct nvmm_x64_state *state = &cpudata->state;
 
-       state->drs[NVMM_X64_DR_DR0] = rdr0();
-       state->drs[NVMM_X64_DR_DR1] = rdr1();
-       state->drs[NVMM_X64_DR_DR2] = rdr2();
-       state->drs[NVMM_X64_DR_DR3] = rdr3();
+       cpudata->drs[NVMM_X64_DR_DR0] = rdr0();
+       cpudata->drs[NVMM_X64_DR_DR1] = rdr1();
+       cpudata->drs[NVMM_X64_DR_DR2] = rdr2();
+       cpudata->drs[NVMM_X64_DR_DR3] = rdr3();
 
        x86_dbregs_restore(curlwp);
 }
@@ -1216,7 +1210,7 @@
        while (1) {
                s = splhigh();
                svm_vcpu_guest_fpu_enter(vcpu);
-               svm_vmrun(cpudata->vmcb_pa, cpudata->state.gprs);
+               svm_vmrun(cpudata->vmcb_pa, cpudata->gprs);
                svm_vcpu_guest_fpu_leave(vcpu);
                splx(s);



Home | Main Index | Thread Index | Old Index