Source-Changes-HG archive

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

[src/trunk]: src Use the comm page to inject events, rather than ioctls, and ...



details:   https://anonhg.NetBSD.org/src/rev/e4fa40853db8
branches:  trunk
changeset: 450948:e4fa40853db8
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed May 01 09:20:21 2019 +0000

description:
Use the comm page to inject events, rather than ioctls, and commit them in
vcpu_run. This saves a few syscalls and copyins.

For example on Windows 10, moving the mouse from the left to right sides of
the screen generates ~500 events, which now don't result in syscalls.

The error handling is done in vcpu_run and it is less precise, but this
doesn't matter a lot, and will be solved with future NVMM error codes.

diffstat:

 lib/libnvmm/libnvmm.c           |  17 +++----
 sys/dev/nvmm/nvmm.c             |   6 +-
 sys/dev/nvmm/nvmm.h             |  14 ++++++-
 sys/dev/nvmm/nvmm_internal.h    |   5 +-
 sys/dev/nvmm/nvmm_ioctl.h       |   3 +-
 sys/dev/nvmm/x86/nvmm_x86.h     |  11 +---
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  78 ++++++++++++++++++++++--------------
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  86 ++++++++++++++++++++++++----------------
 8 files changed, 130 insertions(+), 90 deletions(-)

diffs (truncated from 521 to 300 lines):

diff -r 7347c1fa55f1 -r e4fa40853db8 lib/libnvmm/libnvmm.c
--- a/lib/libnvmm/libnvmm.c     Wed May 01 08:53:00 2019 +0000
+++ b/lib/libnvmm/libnvmm.c     Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libnvmm.c,v 1.11 2019/04/29 17:27:57 maxv Exp $        */
+/*     $NetBSD: libnvmm.c,v 1.12 2019/05/01 09:20:21 maxv Exp $        */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -362,16 +362,15 @@
 nvmm_vcpu_inject(struct nvmm_machine *mach, nvmm_cpuid_t cpuid,
     struct nvmm_event *event)
 {
-       struct nvmm_ioc_vcpu_inject args;
-       int ret;
+       struct nvmm_comm_page *comm;
 
-       args.machid = mach->machid;
-       args.cpuid = cpuid;
-       memcpy(&args.event, event, sizeof(args.event));
+       if (__predict_false(cpuid >= mach->npages)) {
+               return -1;
+       }
+       comm = mach->pages[cpuid];
 
-       ret = ioctl(nvmm_fd, NVMM_IOC_VCPU_INJECT, &args);
-       if (ret == -1)
-               return -1;
+       memcpy(&comm->event, event, sizeof(comm->event));
+       comm->event_commit = true;
 
        return 0;
 }
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/nvmm.c
--- a/sys/dev/nvmm/nvmm.c       Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/nvmm.c       Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm.c,v 1.19 2019/04/28 14:22:13 maxv Exp $   */
+/*     $NetBSD: nvmm.c,v 1.20 2019/05/01 09:20:21 maxv Exp $   */
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.19 2019/04/28 14:22:13 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm.c,v 1.20 2019/05/01 09:20:21 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -503,7 +503,7 @@
        if (error)
                goto out;
 
-       error = (*nvmm_impl->vcpu_inject)(mach, vcpu, &args->event);
+       error = (*nvmm_impl->vcpu_inject)(vcpu);
        nvmm_vcpu_put(vcpu);
 
 out:
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/nvmm.h
--- a/sys/dev/nvmm/nvmm.h       Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/nvmm.h       Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm.h,v 1.8 2019/04/28 14:22:13 maxv Exp $    */
+/*     $NetBSD: nvmm.h,v 1.9 2019/05/01 09:20:21 maxv Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -94,6 +94,18 @@
        struct nvmm_cap_md arch;
 };
 
+struct nvmm_comm_page {
+       /* State. */
+       uint64_t state_wanted;
+       uint64_t state_cached;
+       uint64_t state_commit;
+       struct nvmm_vcpu_state state;
+
+       /* Event. */
+       bool event_commit;
+       struct nvmm_event event;
+};
+
 /*
  * Bits 20:27 -> machid
  * Bits 12:19 -> cpuid
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/nvmm_internal.h
--- a/sys/dev/nvmm/nvmm_internal.h      Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/nvmm_internal.h      Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_internal.h,v 1.10 2019/04/28 14:22:13 maxv Exp $  */
+/*     $NetBSD: nvmm_internal.h,v 1.11 2019/05/01 09:20:21 maxv Exp $  */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -107,8 +107,7 @@
        void (*vcpu_destroy)(struct nvmm_machine *, struct nvmm_cpu *);
        void (*vcpu_setstate)(struct nvmm_cpu *);
        void (*vcpu_getstate)(struct nvmm_cpu *);
-       int (*vcpu_inject)(struct nvmm_machine *, struct nvmm_cpu *,
-           struct nvmm_event *);
+       int (*vcpu_inject)(struct nvmm_cpu *);
        int (*vcpu_run)(struct nvmm_machine *, struct nvmm_cpu *,
            struct nvmm_exit *);
 };
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/nvmm_ioctl.h
--- a/sys/dev/nvmm/nvmm_ioctl.h Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/nvmm_ioctl.h Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_ioctl.h,v 1.6 2019/04/28 14:22:13 maxv Exp $      */
+/*     $NetBSD: nvmm_ioctl.h,v 1.7 2019/05/01 09:20:21 maxv Exp $      */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -75,7 +75,6 @@
 struct nvmm_ioc_vcpu_inject {
        nvmm_machid_t machid;
        nvmm_cpuid_t cpuid;
-       struct nvmm_event event;
 };
 
 struct nvmm_ioc_vcpu_run {
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/x86/nvmm_x86.h
--- a/sys/dev/nvmm/x86/nvmm_x86.h       Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.h       Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86.h,v 1.13 2019/04/28 14:22:13 maxv Exp $       */
+/*     $NetBSD: nvmm_x86.h,v 1.14 2019/05/01 09:20:21 maxv Exp $       */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -229,6 +229,8 @@
        struct fxsave fpu;
 };
 
+#define nvmm_vcpu_state nvmm_x64_state
+
 #define NVMM_X86_CONF_CPUID    0
 #define NVMM_X86_NCONF         1
 
@@ -248,13 +250,6 @@
        } del;
 };
 
-struct nvmm_comm_page {
-       uint64_t state_wanted;
-       uint64_t state_cached;
-       uint64_t state_commit;
-       struct nvmm_x64_state state;
-};
-
 #ifdef _KERNEL
 struct nvmm_x86_cpuid_mask {
        uint32_t eax;
diff -r 7347c1fa55f1 -r e4fa40853db8 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Wed May 01 08:53:00 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Wed May 01 09:20:21 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.44 2019/04/29 18:54:25 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.45 2019/05/01 09:20:21 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.44 2019/04/29 18:54:25 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.45 2019/05/01 09:20:21 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -661,46 +661,51 @@
 }
 
 static int
-svm_vcpu_inject(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
-    struct nvmm_event *event)
+svm_vcpu_inject(struct nvmm_cpu *vcpu)
 {
+       struct nvmm_comm_page *comm = vcpu->comm;
        struct svm_cpudata *cpudata = vcpu->cpudata;
        struct vmcb *vmcb = cpudata->vmcb;
+       enum nvmm_event_type evtype;
+       uint64_t vector, error;
        int type = 0, err = 0;
 
-       if (event->vector >= 256) {
+       evtype = comm->event.type;
+       vector = comm->event.vector;
+       error = comm->event.u.error;
+       __insn_barrier();
+
+       if (__predict_false(vector >= 256)) {
                return EINVAL;
        }
 
-       switch (event->type) {
+       switch (evtype) {
        case NVMM_EVENT_INTERRUPT_HW:
                type = SVM_EVENT_TYPE_HW_INT;
-               if (event->vector == 2) {
+               if (vector == 2) {
                        type = SVM_EVENT_TYPE_NMI;
                        svm_event_waitexit_enable(vcpu, true);
                }
                err = 0;
                break;
-       case NVMM_EVENT_INTERRUPT_SW:
-               return EINVAL;
        case NVMM_EVENT_EXCEPTION:
                type = SVM_EVENT_TYPE_EXC;
-               if (event->vector == 2 || event->vector >= 32)
+               if (vector == 2 || vector >= 32)
                        return EINVAL;
-               if (event->vector == 3 || event->vector == 0)
+               if (vector == 3 || vector == 0)
                        return EINVAL;
-               err = svm_event_has_error(event->vector);
+               err = svm_event_has_error(vector);
                break;
        default:
                return EINVAL;
        }
 
        vmcb->ctrl.eventinj =
-           __SHIFTIN(event->vector, VMCB_CTRL_EVENTINJ_VECTOR) |
+           __SHIFTIN(vector, VMCB_CTRL_EVENTINJ_VECTOR) |
            __SHIFTIN(type, VMCB_CTRL_EVENTINJ_TYPE) |
            __SHIFTIN(err, VMCB_CTRL_EVENTINJ_EV) |
            __SHIFTIN(1, VMCB_CTRL_EVENTINJ_V) |
-           __SHIFTIN(event->u.error, VMCB_CTRL_EVENTINJ_ERRORCODE);
+           __SHIFTIN(error, VMCB_CTRL_EVENTINJ_ERRORCODE);
 
        cpudata->evt_pending = true;
 
@@ -708,31 +713,41 @@
 }
 
 static void
-svm_inject_ud(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
+svm_inject_ud(struct nvmm_cpu *vcpu)
 {
-       struct nvmm_event event;
+       struct nvmm_comm_page *comm = vcpu->comm;
        int ret __diagused;
 
-       event.type = NVMM_EVENT_EXCEPTION;
-       event.vector = 6;
-       event.u.error = 0;
+       comm->event.type = NVMM_EVENT_EXCEPTION;
+       comm->event.vector = 6;
+       comm->event.u.error = 0;
 
-       ret = svm_vcpu_inject(mach, vcpu, &event);
+       ret = svm_vcpu_inject(vcpu);
        KASSERT(ret == 0);
 }
 
 static void
-svm_inject_gp(struct nvmm_machine *mach, struct nvmm_cpu *vcpu)
+svm_inject_gp(struct nvmm_cpu *vcpu)
 {
-       struct nvmm_event event;
+       struct nvmm_comm_page *comm = vcpu->comm;
        int ret __diagused;
 
-       event.type = NVMM_EVENT_EXCEPTION;
-       event.vector = 13;
-       event.u.error = 0;
+       comm->event.type = NVMM_EVENT_EXCEPTION;
+       comm->event.vector = 13;
+       comm->event.u.error = 0;
+
+       ret = svm_vcpu_inject(vcpu);
+       KASSERT(ret == 0);
+}
 
-       ret = svm_vcpu_inject(mach, vcpu, &event);
-       KASSERT(ret == 0);
+static inline int 
+svm_vcpu_event_commit(struct nvmm_cpu *vcpu)
+{
+       if (__predict_true(!vcpu->comm->event_commit)) {
+               return 0;
+       }
+       vcpu->comm->event_commit = false;
+       return svm_vcpu_inject(vcpu);
 }
 
 static inline void
@@ -1018,7 +1033,7 @@
        return true;
 
 error:
-       svm_inject_gp(mach, vcpu);
+       svm_inject_gp(vcpu);
        return true;



Home | Main Index | Thread Index | Old Index