Module Name: src Committed By: maxv Date: Mon Feb 4 12:11:18 UTC 2019
Modified Files: src/sys/dev/nvmm/x86: nvmm_x86_svm.c Log Message: Improvements: - Guest reads/writes to PAT land in gPAT, so no need to emulate them. - When emulating EFER, don't advance the RIP if a fault occurs, and don't forget to flush the VMCB cache accordingly. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/dev/nvmm/x86/nvmm_x86_svm.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/nvmm/x86/nvmm_x86_svm.c diff -u src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.18 src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.19 --- src/sys/dev/nvmm/x86/nvmm_x86_svm.c:1.18 Sat Jan 26 15:12:20 2019 +++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c Mon Feb 4 12:11:18 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nvmm_x86_svm.c,v 1.18 2019/01/26 15:12:20 maxv Exp $ */ +/* $NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11: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.18 2019/01/26 15:12:20 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.19 2019/02/04 12:11:18 maxv Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -938,20 +938,15 @@ svm_inkernel_handle_msr(struct nvmm_mach struct nvmm_exit *exit) { struct svm_cpudata *cpudata = vcpu->cpudata; + struct vmcb *vmcb = cpudata->vmcb; uint64_t val; size_t i; switch (exit->u.msr.type) { case NVMM_EXIT_MSR_RDMSR: - if (exit->u.msr.msr == MSR_CR_PAT) { - val = cpudata->vmcb->state.g_pat; - cpudata->vmcb->state.rax = (val & 0xFFFFFFFF); - 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); + vmcb->state.rax = (val & 0xFFFFFFFF); cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); goto handled; } @@ -959,7 +954,7 @@ svm_inkernel_handle_msr(struct nvmm_mach if (msr_ignore_list[i] != exit->u.msr.msr) continue; val = 0; - cpudata->vmcb->state.rax = (val & 0xFFFFFFFF); + vmcb->state.rax = (val & 0xFFFFFFFF); cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); goto handled; } @@ -967,18 +962,14 @@ svm_inkernel_handle_msr(struct nvmm_mach case NVMM_EXIT_MSR_WRMSR: if (exit->u.msr.msr == MSR_EFER) { if (__predict_false(exit->u.msr.val & ~EFER_VALID)) { - svm_inject_gp(mach, vcpu); - goto handled; + goto error; } - if ((cpudata->vmcb->state.efer ^ exit->u.msr.val) & + if ((vmcb->state.efer ^ exit->u.msr.val) & EFER_TLB_FLUSH) { cpudata->tlb_want_flush = true; } - cpudata->vmcb->state.efer = exit->u.msr.val | EFER_SVME; - goto handled; - } - if (exit->u.msr.msr == MSR_CR_PAT) { - cpudata->vmcb->state.g_pat = exit->u.msr.val; + vmcb->state.efer = exit->u.msr.val | EFER_SVME; + vmcb->ctrl.vmcb_clean &= ~VMCB_CTRL_VMCB_CLEAN_CR; goto handled; } for (i = 0; i < __arraycount(msr_ignore_list); i++) { @@ -994,6 +985,10 @@ svm_inkernel_handle_msr(struct nvmm_mach handled: svm_inkernel_advance(cpudata->vmcb); return true; + +error: + svm_inject_gp(mach, vcpu); + return true; } static void @@ -1557,6 +1552,7 @@ svm_vcpu_init(struct nvmm_machine *mach, * - SYSENTER_EIP [read, write] * - FSBASE [read, write] * - GSBASE [read, write] + * - PAT [read, write] * - TSC [read] * * Intercept the rest. @@ -1573,6 +1569,7 @@ svm_vcpu_init(struct nvmm_machine *mach, svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_EIP, true, true); svm_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true); svm_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true); + svm_vcpu_msr_allow(cpudata->msrbm, MSR_CR_PAT, true, true); svm_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false); vmcb->ctrl.msrpm_base_pa = cpudata->msrbm_pa;