xref: /illumos-gate/usr/src/uts/intel/io/vmm/amd/svm_msr.c (revision 7c8c0b8227679b4684566e408ccc96d6ef7175e9)
1*7c8c0b82SPatrick Mooney /*-
2*7c8c0b82SPatrick Mooney  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*7c8c0b82SPatrick Mooney  *
4*7c8c0b82SPatrick Mooney  * Copyright (c) 2014, Neel Natu (neel@freebsd.org)
5*7c8c0b82SPatrick Mooney  * All rights reserved.
6*7c8c0b82SPatrick Mooney  *
7*7c8c0b82SPatrick Mooney  * Redistribution and use in source and binary forms, with or without
8*7c8c0b82SPatrick Mooney  * modification, are permitted provided that the following conditions
9*7c8c0b82SPatrick Mooney  * are met:
10*7c8c0b82SPatrick Mooney  * 1. Redistributions of source code must retain the above copyright
11*7c8c0b82SPatrick Mooney  *    notice unmodified, this list of conditions, and the following
12*7c8c0b82SPatrick Mooney  *    disclaimer.
13*7c8c0b82SPatrick Mooney  * 2. Redistributions in binary form must reproduce the above copyright
14*7c8c0b82SPatrick Mooney  *    notice, this list of conditions and the following disclaimer in the
15*7c8c0b82SPatrick Mooney  *    documentation and/or other materials provided with the distribution.
16*7c8c0b82SPatrick Mooney  *
17*7c8c0b82SPatrick Mooney  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18*7c8c0b82SPatrick Mooney  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19*7c8c0b82SPatrick Mooney  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20*7c8c0b82SPatrick Mooney  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21*7c8c0b82SPatrick Mooney  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22*7c8c0b82SPatrick Mooney  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23*7c8c0b82SPatrick Mooney  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*7c8c0b82SPatrick Mooney  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*7c8c0b82SPatrick Mooney  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26*7c8c0b82SPatrick Mooney  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*7c8c0b82SPatrick Mooney  */
28*7c8c0b82SPatrick Mooney /*
29*7c8c0b82SPatrick Mooney  * This file and its contents are supplied under the terms of the
30*7c8c0b82SPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
31*7c8c0b82SPatrick Mooney  * You may only use this file in accordance with the terms of version
32*7c8c0b82SPatrick Mooney  * 1.0 of the CDDL.
33*7c8c0b82SPatrick Mooney  *
34*7c8c0b82SPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
35*7c8c0b82SPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
36*7c8c0b82SPatrick Mooney  * http://www.illumos.org/license/CDDL.
37*7c8c0b82SPatrick Mooney  *
38*7c8c0b82SPatrick Mooney  * Copyright 2020 Oxide Computer Company
39*7c8c0b82SPatrick Mooney  */
40*7c8c0b82SPatrick Mooney 
41*7c8c0b82SPatrick Mooney #include <sys/cdefs.h>
42*7c8c0b82SPatrick Mooney __FBSDID("$FreeBSD$");
43*7c8c0b82SPatrick Mooney 
44*7c8c0b82SPatrick Mooney #include <sys/param.h>
45*7c8c0b82SPatrick Mooney #include <sys/errno.h>
46*7c8c0b82SPatrick Mooney #include <sys/systm.h>
47*7c8c0b82SPatrick Mooney #include <sys/x86_archext.h>
48*7c8c0b82SPatrick Mooney #include <sys/privregs.h>
49*7c8c0b82SPatrick Mooney 
50*7c8c0b82SPatrick Mooney #include <machine/cpufunc.h>
51*7c8c0b82SPatrick Mooney #include <machine/specialreg.h>
52*7c8c0b82SPatrick Mooney #include <machine/vmm.h>
53*7c8c0b82SPatrick Mooney #include <sys/vmm_kernel.h>
54*7c8c0b82SPatrick Mooney 
55*7c8c0b82SPatrick Mooney #include "svm.h"
56*7c8c0b82SPatrick Mooney #include "vmcb.h"
57*7c8c0b82SPatrick Mooney #include "svm_softc.h"
58*7c8c0b82SPatrick Mooney #include "svm_msr.h"
59*7c8c0b82SPatrick Mooney 
60*7c8c0b82SPatrick Mooney #ifndef MSR_AMDK8_IPM
61*7c8c0b82SPatrick Mooney #define	MSR_AMDK8_IPM	0xc0010055
62*7c8c0b82SPatrick Mooney #endif
63*7c8c0b82SPatrick Mooney 
64*7c8c0b82SPatrick Mooney enum {
65*7c8c0b82SPatrick Mooney 	IDX_MSR_LSTAR,
66*7c8c0b82SPatrick Mooney 	IDX_MSR_CSTAR,
67*7c8c0b82SPatrick Mooney 	IDX_MSR_STAR,
68*7c8c0b82SPatrick Mooney 	IDX_MSR_SF_MASK,
69*7c8c0b82SPatrick Mooney 	HOST_MSR_NUM		/* must be the last enumeration */
70*7c8c0b82SPatrick Mooney };
71*7c8c0b82SPatrick Mooney CTASSERT(HOST_MSR_NUM == SVM_HOST_MSR_NUM);
72*7c8c0b82SPatrick Mooney 
73*7c8c0b82SPatrick Mooney void
74*7c8c0b82SPatrick Mooney svm_msr_init(void)
75*7c8c0b82SPatrick Mooney {
76*7c8c0b82SPatrick Mooney 	/*
77*7c8c0b82SPatrick Mooney 	 * These MSRs do vary between CPUs on illumos, so saving system-wide
78*7c8c0b82SPatrick Mooney 	 * values for them serves no purpose.
79*7c8c0b82SPatrick Mooney 	 */
80*7c8c0b82SPatrick Mooney }
81*7c8c0b82SPatrick Mooney 
82*7c8c0b82SPatrick Mooney void
83*7c8c0b82SPatrick Mooney svm_msr_guest_init(struct svm_softc *sc, int vcpu)
84*7c8c0b82SPatrick Mooney {
85*7c8c0b82SPatrick Mooney 	/*
86*7c8c0b82SPatrick Mooney 	 * All the MSRs accessible to the guest are either saved/restored by
87*7c8c0b82SPatrick Mooney 	 * hardware on every #VMEXIT/VMRUN (e.g., G_PAT) or are saved/restored
88*7c8c0b82SPatrick Mooney 	 * by VMSAVE/VMLOAD (e.g., MSR_GSBASE).
89*7c8c0b82SPatrick Mooney 	 *
90*7c8c0b82SPatrick Mooney 	 * There are no guest MSRs that are saved/restored "by hand" so nothing
91*7c8c0b82SPatrick Mooney 	 * more to do here.
92*7c8c0b82SPatrick Mooney 	 */
93*7c8c0b82SPatrick Mooney }
94*7c8c0b82SPatrick Mooney 
95*7c8c0b82SPatrick Mooney void
96*7c8c0b82SPatrick Mooney svm_msr_guest_enter(struct svm_softc *sc, int vcpu)
97*7c8c0b82SPatrick Mooney {
98*7c8c0b82SPatrick Mooney 	uint64_t *host_msrs = sc->host_msrs[vcpu];
99*7c8c0b82SPatrick Mooney 
100*7c8c0b82SPatrick Mooney 	/*
101*7c8c0b82SPatrick Mooney 	 * Save host MSRs (if any) and restore guest MSRs (if any).
102*7c8c0b82SPatrick Mooney 	 */
103*7c8c0b82SPatrick Mooney 	host_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR);
104*7c8c0b82SPatrick Mooney 	host_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR);
105*7c8c0b82SPatrick Mooney 	host_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR);
106*7c8c0b82SPatrick Mooney 	host_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK);
107*7c8c0b82SPatrick Mooney }
108*7c8c0b82SPatrick Mooney 
109*7c8c0b82SPatrick Mooney void
110*7c8c0b82SPatrick Mooney svm_msr_guest_exit(struct svm_softc *sc, int vcpu)
111*7c8c0b82SPatrick Mooney {
112*7c8c0b82SPatrick Mooney 	uint64_t *host_msrs = sc->host_msrs[vcpu];
113*7c8c0b82SPatrick Mooney 
114*7c8c0b82SPatrick Mooney 	/*
115*7c8c0b82SPatrick Mooney 	 * Save guest MSRs (if any) and restore host MSRs.
116*7c8c0b82SPatrick Mooney 	 */
117*7c8c0b82SPatrick Mooney 	wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]);
118*7c8c0b82SPatrick Mooney 	wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]);
119*7c8c0b82SPatrick Mooney 	wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]);
120*7c8c0b82SPatrick Mooney 	wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]);
121*7c8c0b82SPatrick Mooney 
122*7c8c0b82SPatrick Mooney 	/* MSR_KGSBASE will be restored on the way back to userspace */
123*7c8c0b82SPatrick Mooney }
124*7c8c0b82SPatrick Mooney 
125*7c8c0b82SPatrick Mooney vm_msr_result_t
126*7c8c0b82SPatrick Mooney svm_rdmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t *result)
127*7c8c0b82SPatrick Mooney {
128*7c8c0b82SPatrick Mooney 	switch (num) {
129*7c8c0b82SPatrick Mooney 	case MSR_SYSCFG:
130*7c8c0b82SPatrick Mooney 	case MSR_AMDK8_IPM:
131*7c8c0b82SPatrick Mooney 	case MSR_EXTFEATURES:
132*7c8c0b82SPatrick Mooney 		*result = 0;
133*7c8c0b82SPatrick Mooney 		break;
134*7c8c0b82SPatrick Mooney 	case MSR_AMD_DE_CFG:
135*7c8c0b82SPatrick Mooney 		*result = 0;
136*7c8c0b82SPatrick Mooney 		/*
137*7c8c0b82SPatrick Mooney 		 * Bit 1 of DE_CFG is defined by AMD to control whether the
138*7c8c0b82SPatrick Mooney 		 * lfence instruction is serializing.  Practically all CPUs
139*7c8c0b82SPatrick Mooney 		 * supported by bhyve also contain this MSR, making it safe to
140*7c8c0b82SPatrick Mooney 		 * expose unconditionally.
141*7c8c0b82SPatrick Mooney 		 */
142*7c8c0b82SPatrick Mooney 		if (is_x86_feature(x86_featureset, X86FSET_LFENCE_SER)) {
143*7c8c0b82SPatrick Mooney 			*result |= AMD_DE_CFG_LFENCE_DISPATCH;
144*7c8c0b82SPatrick Mooney 		}
145*7c8c0b82SPatrick Mooney 		break;
146*7c8c0b82SPatrick Mooney 	default:
147*7c8c0b82SPatrick Mooney 		return (VMR_UNHANLDED);
148*7c8c0b82SPatrick Mooney 	}
149*7c8c0b82SPatrick Mooney 	return (VMR_OK);
150*7c8c0b82SPatrick Mooney }
151*7c8c0b82SPatrick Mooney 
152*7c8c0b82SPatrick Mooney vm_msr_result_t
153*7c8c0b82SPatrick Mooney svm_wrmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t val)
154*7c8c0b82SPatrick Mooney {
155*7c8c0b82SPatrick Mooney 	switch (num) {
156*7c8c0b82SPatrick Mooney 	case MSR_SYSCFG:
157*7c8c0b82SPatrick Mooney 		/* Ignore writes */
158*7c8c0b82SPatrick Mooney 		break;
159*7c8c0b82SPatrick Mooney 	case MSR_AMD_DE_CFG:
160*7c8c0b82SPatrick Mooney 		/* Ignore writes */
161*7c8c0b82SPatrick Mooney 		break;
162*7c8c0b82SPatrick Mooney 	case MSR_AMDK8_IPM:
163*7c8c0b82SPatrick Mooney 		/*
164*7c8c0b82SPatrick Mooney 		 * Ignore writes to the "Interrupt Pending Message" MSR.
165*7c8c0b82SPatrick Mooney 		 */
166*7c8c0b82SPatrick Mooney 		break;
167*7c8c0b82SPatrick Mooney 	case MSR_K8_UCODE_UPDATE:
168*7c8c0b82SPatrick Mooney 		/*
169*7c8c0b82SPatrick Mooney 		 * Ignore writes to microcode update register.
170*7c8c0b82SPatrick Mooney 		 */
171*7c8c0b82SPatrick Mooney 		break;
172*7c8c0b82SPatrick Mooney 	case MSR_EXTFEATURES:
173*7c8c0b82SPatrick Mooney 		break;
174*7c8c0b82SPatrick Mooney 	default:
175*7c8c0b82SPatrick Mooney 		return (VMR_UNHANLDED);
176*7c8c0b82SPatrick Mooney 	}
177*7c8c0b82SPatrick Mooney 
178*7c8c0b82SPatrick Mooney 	return (VMR_OK);
179*7c8c0b82SPatrick Mooney }
180