Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Improvements in NVMM
details: https://anonhg.NetBSD.org/src/rev/98def5edfb92
branches: trunk
changeset: 448064:98def5edfb92
user: maxv <maxv%NetBSD.org@localhost>
date: Sun Jan 20 16:55:21 2019 +0000
description:
Improvements in NVMM
* Handle the FPU differently, limit the states via the given mask rather
than via XCR0. Align to 64 bytes. Provide an initial gXCR0, to be sure
that XCR0_X87 is set. Reset XSTATE_BV when the state is modified by
the virtualizer, to force a reload from memory.
* Hide RDTSCP.
* Zero-extend RBX/RCX/RDX when handling the NVMM CPUID signature.
* Take ECX and not RCX on MSR instructions.
diffstat:
sys/arch/x86/include/fpu.h | 6 ++--
sys/arch/x86/x86/fpu.c | 18 +++++++-------
sys/dev/nvmm/x86/nvmm_x86_svm.c | 52 +++++++++++++++++++++++-----------------
3 files changed, 42 insertions(+), 34 deletions(-)
diffs (239 lines):
diff -r 984ee9763b78 -r 98def5edfb92 sys/arch/x86/include/fpu.h
--- a/sys/arch/x86/include/fpu.h Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/arch/x86/include/fpu.h Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.h,v 1.13 2018/10/05 18:51:52 maxv Exp $ */
+/* $NetBSD: fpu.h,v 1.14 2019/01/20 16:55:21 maxv Exp $ */
#ifndef _X86_FPU_H_
#define _X86_FPU_H_
@@ -14,8 +14,8 @@
void fpuinit(struct cpu_info *);
void fpuinit_mxcsr_mask(void);
-void fpu_area_save(void *);
-void fpu_area_restore(void *);
+void fpu_area_save(void *, uint64_t);
+void fpu_area_restore(void *, uint64_t);
void fpusave_lwp(struct lwp *, bool);
void fpusave_cpu(bool);
diff -r 984ee9763b78 -r 98def5edfb92 sys/arch/x86/x86/fpu.c
--- a/sys/arch/x86/x86/fpu.c Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/arch/x86/x86/fpu.c Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fpu.c,v 1.48 2018/10/05 18:51:52 maxv Exp $ */
+/* $NetBSD: fpu.c,v 1.49 2019/01/20 16:55:21 maxv Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc. All
@@ -96,7 +96,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.48 2018/10/05 18:51:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.49 2019/01/20 16:55:21 maxv Exp $");
#include "opt_multiprocessor.h"
@@ -209,7 +209,7 @@
}
void
-fpu_area_save(void *area)
+fpu_area_save(void *area, uint64_t xsave_features)
{
clts();
@@ -221,16 +221,16 @@
fxsave(area);
break;
case FPU_SAVE_XSAVE:
- xsave(area, x86_xsave_features);
+ xsave(area, xsave_features);
break;
case FPU_SAVE_XSAVEOPT:
- xsaveopt(area, x86_xsave_features);
+ xsaveopt(area, xsave_features);
break;
}
}
void
-fpu_area_restore(void *area)
+fpu_area_restore(void *area, uint64_t xsave_features)
{
clts();
@@ -247,7 +247,7 @@
case FPU_SAVE_XSAVEOPT:
if (cpu_vendor == CPUVENDOR_AMD)
fpu_clear_amd();
- xrstor(area, x86_xsave_features);
+ xrstor(area, xsave_features);
break;
}
}
@@ -262,7 +262,7 @@
KASSERT(pcb->pcb_fpcpu == NULL);
ci->ci_fpcurlwp = l;
pcb->pcb_fpcpu = ci;
- fpu_area_restore(&pcb->pcb_savefpu);
+ fpu_area_restore(&pcb->pcb_savefpu, x86_xsave_features);
}
void
@@ -532,7 +532,7 @@
pcb = lwp_getpcb(l);
if (save) {
- fpu_area_save(&pcb->pcb_savefpu);
+ fpu_area_save(&pcb->pcb_savefpu, x86_xsave_features);
}
stts();
diff -r 984ee9763b78 -r 98def5edfb92 sys/dev/nvmm/x86/nvmm_x86_svm.c
--- a/sys/dev/nvmm/x86/nvmm_x86_svm.c Sun Jan 20 16:02:32 2019 +0000
+++ b/sys/dev/nvmm/x86/nvmm_x86_svm.c Sun Jan 20 16:55:21 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_svm.c,v 1.15 2019/01/13 10:07:50 maxv Exp $ */
+/* $NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55: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.15 2019/01/13 10:07:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.16 2019/01/20 16:55:21 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -524,7 +524,7 @@
uint64_t fsbase;
uint64_t kernelgsbase;
bool ts_set;
- struct xsave_header hfpu __aligned(16);
+ struct xsave_header hfpu __aligned(64);
/* Event state */
bool int_window_exit;
@@ -535,7 +535,7 @@
uint64_t gprs[NVMM_X64_NGPR];
uint64_t drs[NVMM_X64_NDR];
uint64_t tsc_offset;
- struct xsave_header gfpu __aligned(16);
+ struct xsave_header gfpu __aligned(64);
};
static void
@@ -779,12 +779,16 @@
cpudata->gprs[NVMM_X64_GPR_RDX] = svm_xcr0_mask >> 32;
break;
case 0x40000000:
+ cpudata->gprs[NVMM_X64_GPR_RBX] = 0;
+ cpudata->gprs[NVMM_X64_GPR_RCX] = 0;
+ cpudata->gprs[NVMM_X64_GPR_RDX] = 0;
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. */
+ case 0x80000001: /* No SVM, no RDTSCP. The rest is tunable. */
cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID_SVM;
+ cpudata->gprs[NVMM_X64_GPR_RDX] &= ~CPUID_RDTSCP;
break;
default:
break;
@@ -1007,7 +1011,7 @@
exit->u.msr.type = NVMM_EXIT_MSR_WRMSR;
}
- exit->u.msr.msr = cpudata->gprs[NVMM_X64_GPR_RCX];
+ exit->u.msr.msr = (cpudata->gprs[NVMM_X64_GPR_RCX] & 0xFFFFFFFF);
if (info == 1) {
uint64_t rdx, rax;
@@ -1092,15 +1096,15 @@
{
struct svm_cpudata *cpudata = vcpu->cpudata;
- if (x86_xsave_features != 0) {
+ cpudata->ts_set = (rcr0() & CR0_TS) != 0;
+
+ fpu_area_save(&cpudata->hfpu, svm_xcr0_mask);
+ fpu_area_restore(&cpudata->gfpu, svm_xcr0_mask);
+
+ if (svm_xcr0_mask != 0) {
cpudata->hxcr0 = rdxcr(0);
wrxcr(0, cpudata->gxcr0);
}
-
- cpudata->ts_set = (rcr0() & CR0_TS) != 0;
-
- fpu_area_save(&cpudata->hfpu);
- fpu_area_restore(&cpudata->gfpu);
}
static void
@@ -1108,17 +1112,17 @@
{
struct svm_cpudata *cpudata = vcpu->cpudata;
- fpu_area_save(&cpudata->gfpu);
- fpu_area_restore(&cpudata->hfpu);
+ if (svm_xcr0_mask != 0) {
+ cpudata->gxcr0 = rdxcr(0);
+ wrxcr(0, cpudata->hxcr0);
+ }
+
+ fpu_area_save(&cpudata->gfpu, svm_xcr0_mask);
+ fpu_area_restore(&cpudata->hfpu, svm_xcr0_mask);
if (cpudata->ts_set) {
stts();
}
-
- if (x86_xsave_features != 0) {
- cpudata->gxcr0 = rdxcr(0);
- wrxcr(0, cpudata->hxcr0);
- }
}
static void
@@ -1580,6 +1584,7 @@
/* Must always be set. */
vmcb->state.efer = EFER_SVME;
+ cpudata->gxcr0 = XCR0_X87;
/* Init XSAVE header. */
cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
@@ -1779,13 +1784,11 @@
vmcb->ctrl.v |= __SHIFTIN(state->crs[NVMM_X64_CR_CR8],
VMCB_CTRL_V_TPR);
- /* Clear unsupported XCR0 bits, set mandatory X87 bit. */
if (svm_xcr0_mask != 0) {
+ /* Clear illegal XCR0 bits, set mandatory X87 bit. */
cpudata->gxcr0 = state->crs[NVMM_X64_CR_XCR0];
cpudata->gxcr0 &= svm_xcr0_mask;
cpudata->gxcr0 |= XCR0_X87;
- } else {
- cpudata->gxcr0 = 0;
}
}
@@ -1846,6 +1849,11 @@
fpustate = (struct fxsave *)cpudata->gfpu.xsh_fxsave;
fpustate->fx_mxcsr_mask &= x86_fpu_mxcsr_mask;
fpustate->fx_mxcsr &= fpustate->fx_mxcsr_mask;
+
+ if (svm_xcr0_mask != 0) {
+ /* Reset XSTATE_BV, to force a reload. */
+ cpudata->gfpu.xsh_xstate_bv = svm_xcr0_mask;
+ }
}
svm_vmcb_cache_update(vmcb, flags);
Home |
Main Index |
Thread Index |
Old Index