Wed Aug 26 16:33:03 2020 UTC ()
nvmm-x86-svm: improve the handling of MSR_EFER

Intercept reads of it as well, just to mask EFER_SVME, which the guest
doesn't need to see.


(maxv)
diff -r1.73 -r1.74 src/sys/dev/nvmm/x86/nvmm_x86_svm.c

cvs diff -r1.73 -r1.74 src/sys/dev/nvmm/x86/nvmm_x86_svm.c (expand / switch to unified diff)

--- src/sys/dev/nvmm/x86/nvmm_x86_svm.c 2020/08/26 16:32:02 1.73
+++ src/sys/dev/nvmm/x86/nvmm_x86_svm.c 2020/08/26 16:33:03 1.74
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $ */ 1/* $NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2018-2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018-2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Maxime Villard. 8 * by Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.73 2020/08/26 16:32:02 maxv Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_svm.c,v 1.74 2020/08/26 16:33:03 maxv Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/cpu.h> 39#include <sys/cpu.h>
40#include <sys/xcall.h> 40#include <sys/xcall.h>
41#include <sys/mman.h> 41#include <sys/mman.h>
42 42
43#include <uvm/uvm.h> 43#include <uvm/uvm.h>
44#include <uvm/uvm_page.h> 44#include <uvm/uvm_page.h>
45 45
46#include <x86/cputypes.h> 46#include <x86/cputypes.h>
@@ -1160,26 +1160,32 @@ static const uint64_t msr_ignore_list[]  @@ -1160,26 +1160,32 @@ static const uint64_t msr_ignore_list[]
1160 MSR_UCODE_AMD_PATCHLEVEL 1160 MSR_UCODE_AMD_PATCHLEVEL
1161}; 1161};
1162 1162
1163static bool 1163static bool
1164svm_inkernel_handle_msr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu, 1164svm_inkernel_handle_msr(struct nvmm_machine *mach, struct nvmm_cpu *vcpu,
1165 struct nvmm_vcpu_exit *exit) 1165 struct nvmm_vcpu_exit *exit)
1166{ 1166{
1167 struct svm_cpudata *cpudata = vcpu->cpudata; 1167 struct svm_cpudata *cpudata = vcpu->cpudata;
1168 struct vmcb *vmcb = cpudata->vmcb; 1168 struct vmcb *vmcb = cpudata->vmcb;
1169 uint64_t val; 1169 uint64_t val;
1170 size_t i; 1170 size_t i;
1171 1171
1172 if (exit->reason == NVMM_VCPU_EXIT_RDMSR) { 1172 if (exit->reason == NVMM_VCPU_EXIT_RDMSR) {
 1173 if (exit->u.rdmsr.msr == MSR_EFER) {
 1174 val = vmcb->state.efer & ~EFER_SVME;
 1175 vmcb->state.rax = (val & 0xFFFFFFFF);
 1176 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
 1177 goto handled;
 1178 }
1173 if (exit->u.rdmsr.msr == MSR_NB_CFG) { 1179 if (exit->u.rdmsr.msr == MSR_NB_CFG) {
1174 val = NB_CFG_INITAPICCPUIDLO; 1180 val = NB_CFG_INITAPICCPUIDLO;
1175 vmcb->state.rax = (val & 0xFFFFFFFF); 1181 vmcb->state.rax = (val & 0xFFFFFFFF);
1176 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1182 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
1177 goto handled; 1183 goto handled;
1178 } 1184 }
1179 for (i = 0; i < __arraycount(msr_ignore_list); i++) { 1185 for (i = 0; i < __arraycount(msr_ignore_list); i++) {
1180 if (msr_ignore_list[i] != exit->u.rdmsr.msr) 1186 if (msr_ignore_list[i] != exit->u.rdmsr.msr)
1181 continue; 1187 continue;
1182 val = 0; 1188 val = 0;
1183 vmcb->state.rax = (val & 0xFFFFFFFF); 1189 vmcb->state.rax = (val & 0xFFFFFFFF);
1184 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32); 1190 cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
1185 goto handled; 1191 goto handled;
@@ -2185,27 +2191,26 @@ svm_vcpu_init(struct nvmm_machine *mach, @@ -2185,27 +2191,26 @@ svm_vcpu_init(struct nvmm_machine *mach,
2185 */ 2191 */
2186 vmcb->ctrl.intercept_misc3 = 2192 vmcb->ctrl.intercept_misc3 =
2187 VMCB_CTRL_INTERCEPT_INVLPGB_ALL | 2193 VMCB_CTRL_INTERCEPT_INVLPGB_ALL |
2188 VMCB_CTRL_INTERCEPT_PCID | 2194 VMCB_CTRL_INTERCEPT_PCID |
2189 VMCB_CTRL_INTERCEPT_MCOMMIT | 2195 VMCB_CTRL_INTERCEPT_MCOMMIT |
2190 VMCB_CTRL_INTERCEPT_TLBSYNC; 2196 VMCB_CTRL_INTERCEPT_TLBSYNC;
2191 2197
2192 /* Intercept all I/O accesses. */ 2198 /* Intercept all I/O accesses. */
2193 memset(cpudata->iobm, 0xFF, IOBM_SIZE); 2199 memset(cpudata->iobm, 0xFF, IOBM_SIZE);
2194 vmcb->ctrl.iopm_base_pa = cpudata->iobm_pa; 2200 vmcb->ctrl.iopm_base_pa = cpudata->iobm_pa;
2195 2201
2196 /* Allow direct access to certain MSRs. */ 2202 /* Allow direct access to certain MSRs. */
2197 memset(cpudata->msrbm, 0xFF, MSRBM_SIZE); 2203 memset(cpudata->msrbm, 0xFF, MSRBM_SIZE);
2198 svm_vcpu_msr_allow(cpudata->msrbm, MSR_EFER, true, false); 
2199 svm_vcpu_msr_allow(cpudata->msrbm, MSR_STAR, true, true); 2204 svm_vcpu_msr_allow(cpudata->msrbm, MSR_STAR, true, true);
2200 svm_vcpu_msr_allow(cpudata->msrbm, MSR_LSTAR, true, true); 2205 svm_vcpu_msr_allow(cpudata->msrbm, MSR_LSTAR, true, true);
2201 svm_vcpu_msr_allow(cpudata->msrbm, MSR_CSTAR, true, true); 2206 svm_vcpu_msr_allow(cpudata->msrbm, MSR_CSTAR, true, true);
2202 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SFMASK, true, true); 2207 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SFMASK, true, true);
2203 svm_vcpu_msr_allow(cpudata->msrbm, MSR_KERNELGSBASE, true, true); 2208 svm_vcpu_msr_allow(cpudata->msrbm, MSR_KERNELGSBASE, true, true);
2204 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_CS, true, true); 2209 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_CS, true, true);
2205 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_ESP, true, true); 2210 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_ESP, true, true);
2206 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_EIP, true, true); 2211 svm_vcpu_msr_allow(cpudata->msrbm, MSR_SYSENTER_EIP, true, true);
2207 svm_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true); 2212 svm_vcpu_msr_allow(cpudata->msrbm, MSR_FSBASE, true, true);
2208 svm_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true); 2213 svm_vcpu_msr_allow(cpudata->msrbm, MSR_GSBASE, true, true);
2209 svm_vcpu_msr_allow(cpudata->msrbm, MSR_CR_PAT, true, true); 2214 svm_vcpu_msr_allow(cpudata->msrbm, MSR_CR_PAT, true, true);
2210 svm_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false); 2215 svm_vcpu_msr_allow(cpudata->msrbm, MSR_TSC, true, false);
2211 vmcb->ctrl.msrpm_base_pa = cpudata->msrbm_pa; 2216 vmcb->ctrl.msrpm_base_pa = cpudata->msrbm_pa;