Source-Changes-HG archive

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

[src/trunk]: src Harmonize the handling of the CPL between AMD and Intel.



details:   https://anonhg.NetBSD.org/src/rev/b73fad1119c2
branches:  trunk
changeset: 448938:b73fad1119c2
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Feb 14 14:30:20 2019 +0000

description:
Harmonize the handling of the CPL between AMD and Intel.

AMD has a separate guest CPL field, because on AMD, the SYSCALL/SYSRET
instructions do not force SS.DPL to predefined values. On Intel they do,
so the CPL on Intel is just the guest's SS.DPL value.

Even though technically possible on AMD, there is no sane reason for a
guest kernel to set a non-three SS.DPL, doing that would mess up several
common segmentation practices and wouldn't be compatible with Intel.

So, force the Intel behavior on AMD, by always setting SS.DPL<=>CPL.
Remove the now unused CPL field from nvmm_x64_state::misc[]. This actually
increases performance on AMD: to detect interrupt windows the virtualizer
has to modify some fields of misc[], and because CPL was there, we had to
flush the SEG set of the VMCB cache. Now there is no flush necessary.

While here remove the CPL check for XSETBV on Intel, contrary to AMD
Intel checks the CPL before the intercept, so if we receive an XSETBV
VMEXIT, we are certain that it was executed at CPL=0 in the guest. By the
way my check was wrong in the first place, it was reading SS.RPL instead
of SS.DPL.

diffstat:

 lib/libnvmm/libnvmm_x86.c       |   3 +--
 sys/dev/nvmm/x86/nvmm_x86.h     |  11 +++++------
 sys/dev/nvmm/x86/nvmm_x86_svm.c |  16 ++++++----------
 sys/dev/nvmm/x86/nvmm_x86_vmx.c |  13 ++-----------
 4 files changed, 14 insertions(+), 29 deletions(-)

diffs (163 lines):

diff -r 904afe02df26 -r b73fad1119c2 lib/libnvmm/libnvmm_x86.c
--- a/lib/libnvmm/libnvmm_x86.c Thu Feb 14 13:27:59 2019 +0000
+++ b/lib/libnvmm/libnvmm_x86.c Thu Feb 14 14:30:20 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libnvmm_x86.c,v 1.21 2019/02/12 14:50:21 maxv Exp $    */
+/*     $NetBSD: libnvmm_x86.c,v 1.22 2019/02/14 14:30:20 maxv Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -92,7 +92,6 @@
        printf("| -> CR3=%p\n", (void *)state.crs[NVMM_X64_CR_CR3]);
        printf("| -> CR4=%p\n", (void *)state.crs[NVMM_X64_CR_CR4]);
        printf("| -> CR8=%p\n", (void *)state.crs[NVMM_X64_CR_CR8]);
-       printf("| -> CPL=%p\n", (void *)state.misc[NVMM_X64_MISC_CPL]);
 
        return 0;
 }
diff -r 904afe02df26 -r b73fad1119c2 sys/dev/nvmm/x86/nvmm_x86.h
--- a/sys/dev/nvmm/x86/nvmm_x86.h       Thu Feb 14 13:27:59 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86.h       Thu Feb 14 14:30:20 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86.h,v 1.4 2019/02/13 06:32:45 maxv Exp $        */
+/*     $NetBSD: nvmm_x86.h,v 1.5 2019/02/14 14:30:20 maxv Exp $        */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -98,11 +98,10 @@
 #define NVMM_X64_NMSR                  10
 
 /* Misc. */
-#define NVMM_X64_MISC_CPL              0
-#define NVMM_X64_MISC_INT_SHADOW       1
-#define NVMM_X64_MISC_INT_WINDOW_EXIT  2
-#define NVMM_X64_MISC_NMI_WINDOW_EXIT  3
-#define NVMM_X64_NMISC                 4
+#define NVMM_X64_MISC_INT_SHADOW       0
+#define NVMM_X64_MISC_INT_WINDOW_EXIT  1
+#define NVMM_X64_MISC_NMI_WINDOW_EXIT  2
+#define NVMM_X64_NMISC                 3
 
 #ifndef ASM_NVMM
 
diff -r 904afe02df26 -r b73fad1119c2 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c   Thu Feb 14 13:27:59 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c   Thu Feb 14 14:30:20 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_svm.c,v 1.22 2019/02/13 10:55:13 maxv Exp $   */
+/*     $NetBSD: nvmm_x86_svm.c,v 1.23 2019/02/14 14:30:20 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.22 2019/02/13 10:55:13 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.23 2019/02/14 14:30:20 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -576,10 +576,6 @@
                vmcb->ctrl.vmcb_clean &=
                    ~(VMCB_CTRL_VMCB_CLEAN_CR | VMCB_CTRL_VMCB_CLEAN_NP);
        }
-       if (flags & NVMM_X64_STATE_MISC) {
-               /* SEG for CPL. */
-               vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_SEG;
-       }
 }
 
 static inline void
@@ -1764,6 +1760,8 @@
                    &vmcb->state.ldt);
                svm_vcpu_setstate_seg(&state->segs[NVMM_X64_SEG_TR],
                    &vmcb->state.tr);
+
+               vmcb->state.cpl = state->segs[NVMM_X64_SEG_SS].attrib.dpl;
        }
 
        CTASSERT(sizeof(cpudata->gprs) == sizeof(state->gprs));
@@ -1822,8 +1820,6 @@
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
-               vmcb->state.cpl = state->misc[NVMM_X64_MISC_CPL];
-
                if (state->misc[NVMM_X64_MISC_INT_SHADOW]) {
                        vmcb->ctrl.intr |= VMCB_CTRL_INTR_SHADOW;
                } else {
@@ -1889,6 +1885,8 @@
                    &vmcb->state.ldt);
                svm_vcpu_getstate_seg(&state->segs[NVMM_X64_SEG_TR],
                    &vmcb->state.tr);
+
+               state->segs[NVMM_X64_SEG_SS].attrib.dpl = vmcb->state.cpl;
        }
 
        CTASSERT(sizeof(cpudata->gprs) == sizeof(state->gprs));
@@ -1940,8 +1938,6 @@
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
-               state->misc[NVMM_X64_MISC_CPL] = vmcb->state.cpl;
-
                state->misc[NVMM_X64_MISC_INT_SHADOW] =
                    (vmcb->ctrl.intr & VMCB_CTRL_INTR_SHADOW) != 0;
                state->misc[NVMM_X64_MISC_INT_WINDOW_EXIT] =
diff -r 904afe02df26 -r b73fad1119c2 sys/dev/nvmm/x86/nvmm_x86_vmx.c
--- a/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Thu Feb 14 13:27:59 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_vmx.c   Thu Feb 14 14:30:20 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nvmm_x86_vmx.c,v 1.2 2019/02/14 09:37:31 maxv Exp $    */
+/*     $NetBSD: nvmm_x86_vmx.c,v 1.3 2019/02/14 14:30:20 maxv Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.2 2019/02/14 09:37:31 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.3 2019/02/14 14:30:20 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1430,19 +1430,14 @@
 {
        struct vmx_cpudata *cpudata = vcpu->cpudata;
        uint16_t val;
-       uint64_t ss;
 
        exit->reason = NVMM_EXIT_NONE;
 
        val = (cpudata->gprs[NVMM_X64_GPR_RDX] << 32) |
            (cpudata->gprs[NVMM_X64_GPR_RAX] & 0xFFFFFFFF);
 
-       vmx_vmread(VMCS_GUEST_SS_SELECTOR, &ss);
-
        if (__predict_false(cpudata->gprs[NVMM_X64_GPR_RCX] != 0)) {
                goto error;
-       } else if (__predict_false((ss & SEL_UPL) != 0)) {
-               goto error;
        } else if (__predict_false((val & ~vmx_xcr0_mask) != 0)) {
                goto error;
        } else if (__predict_false((val & XCR0_X87) == 0)) {
@@ -2276,8 +2271,6 @@
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
-               // XXX CPL? not sure
-
                vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
                intstate &= ~(INT_STATE_STI|INT_STATE_MOVSS);
                if (state->misc[NVMM_X64_MISC_INT_SHADOW]) {
@@ -2391,8 +2384,6 @@
        }
 
        if (flags & NVMM_X64_STATE_MISC) {
-               // XXX CPL? not sure
-
                vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
                state->misc[NVMM_X64_MISC_INT_SHADOW] =
                    (intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0;



Home | Main Index | Thread Index | Old Index