15325 bhyve upstream sync 2023 January
[illumos-gate.git] / usr / src / cmd / bhyve / xmsr.c
blob925235f0a0a5be3452125948015f75f32ae0d6a5
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2011 NetApp, Inc.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
28 * $FreeBSD$
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/types.h>
36 #include <machine/cpufunc.h>
37 #include <machine/vmm.h>
38 #include <machine/specialreg.h>
40 #include <vmmapi.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
46 #include "debug.h"
47 #include "xmsr.h"
49 static int cpu_vendor_intel, cpu_vendor_amd, cpu_vendor_hygon;
51 int
52 emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val)
55 if (cpu_vendor_intel) {
56 switch (num) {
57 #ifndef __FreeBSD__
58 case MSR_PERFCTR0:
59 case MSR_PERFCTR1:
60 case MSR_EVNTSEL0:
61 case MSR_EVNTSEL1:
62 return (0);
63 #endif
64 case 0xd04: /* Sandy Bridge uncore PMCs */
65 case 0xc24:
66 return (0);
67 case MSR_BIOS_UPDT_TRIG:
68 return (0);
69 case MSR_BIOS_SIGN:
70 return (0);
71 default:
72 break;
74 } else if (cpu_vendor_amd || cpu_vendor_hygon) {
75 switch (num) {
76 case MSR_HWCR:
78 * Ignore writes to hardware configuration MSR.
80 return (0);
82 case MSR_NB_CFG1:
83 case MSR_LS_CFG:
84 case MSR_IC_CFG:
85 return (0); /* Ignore writes */
87 case MSR_PERFEVSEL0:
88 case MSR_PERFEVSEL1:
89 case MSR_PERFEVSEL2:
90 case MSR_PERFEVSEL3:
91 /* Ignore writes to the PerfEvtSel MSRs */
92 return (0);
94 case MSR_K7_PERFCTR0:
95 case MSR_K7_PERFCTR1:
96 case MSR_K7_PERFCTR2:
97 case MSR_K7_PERFCTR3:
98 /* Ignore writes to the PerfCtr MSRs */
99 return (0);
101 case MSR_P_STATE_CONTROL:
102 /* Ignore write to change the P-state */
103 return (0);
105 default:
106 break;
109 return (-1);
113 emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val)
115 int error = 0;
117 if (cpu_vendor_intel) {
118 switch (num) {
119 case MSR_BIOS_SIGN:
120 case MSR_IA32_PLATFORM_ID:
121 case MSR_PKG_ENERGY_STATUS:
122 case MSR_PP0_ENERGY_STATUS:
123 case MSR_PP1_ENERGY_STATUS:
124 case MSR_DRAM_ENERGY_STATUS:
125 case MSR_MISC_FEATURE_ENABLES:
126 *val = 0;
127 break;
128 case MSR_RAPL_POWER_UNIT:
130 * Use the default value documented in section
131 * "RAPL Interfaces" in Intel SDM vol3.
133 *val = 0x000a1003;
134 break;
135 case MSR_IA32_FEATURE_CONTROL:
137 * Windows guests check this MSR.
138 * Set the lock bit to avoid writes
139 * to this MSR.
141 *val = IA32_FEATURE_CONTROL_LOCK;
142 break;
143 default:
144 error = -1;
145 break;
147 } else if (cpu_vendor_amd || cpu_vendor_hygon) {
148 switch (num) {
149 case MSR_BIOS_SIGN:
150 *val = 0;
151 break;
152 case MSR_HWCR:
154 * Bios and Kernel Developer's Guides for AMD Families
155 * 12H, 14H, 15H and 16H.
157 *val = 0x01000010; /* Reset value */
158 *val |= 1 << 9; /* MONITOR/MWAIT disable */
159 break;
161 case MSR_NB_CFG1:
162 case MSR_LS_CFG:
163 case MSR_IC_CFG:
165 * The reset value is processor family dependent so
166 * just return 0.
168 *val = 0;
169 break;
171 case MSR_PERFEVSEL0:
172 case MSR_PERFEVSEL1:
173 case MSR_PERFEVSEL2:
174 case MSR_PERFEVSEL3:
176 * PerfEvtSel MSRs are not properly virtualized so just
177 * return zero.
179 *val = 0;
180 break;
182 case MSR_K7_PERFCTR0:
183 case MSR_K7_PERFCTR1:
184 case MSR_K7_PERFCTR2:
185 case MSR_K7_PERFCTR3:
187 * PerfCtr MSRs are not properly virtualized so just
188 * return zero.
190 *val = 0;
191 break;
193 case MSR_SMM_ADDR:
194 case MSR_SMM_MASK:
196 * Return the reset value defined in the AMD Bios and
197 * Kernel Developer's Guide.
199 *val = 0;
200 break;
202 case MSR_P_STATE_LIMIT:
203 case MSR_P_STATE_CONTROL:
204 case MSR_P_STATE_STATUS:
205 case MSR_P_STATE_CONFIG(0): /* P0 configuration */
206 *val = 0;
207 break;
210 * OpenBSD guests test bit 0 of this MSR to detect if the
211 * workaround for erratum 721 is already applied.
212 * https://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf
214 case 0xC0011029:
215 *val = 1;
216 break;
218 #ifndef __FreeBSD__
219 case MSR_VM_CR:
221 * We currently don't support nested virt.
222 * Windows seems to ignore the cpuid bits and reads this
223 * MSR anyways.
225 *val = VM_CR_SVMDIS;
226 break;
227 #endif
229 default:
230 error = -1;
231 break;
233 } else {
234 error = -1;
236 return (error);
240 init_msr(void)
242 int error;
243 u_int regs[4];
244 char cpu_vendor[13];
246 do_cpuid(0, regs);
247 ((u_int *)&cpu_vendor)[0] = regs[1];
248 ((u_int *)&cpu_vendor)[1] = regs[3];
249 ((u_int *)&cpu_vendor)[2] = regs[2];
250 cpu_vendor[12] = '\0';
252 error = 0;
253 if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
254 cpu_vendor_amd = 1;
255 } else if (strcmp(cpu_vendor, "HygonGenuine") == 0) {
256 cpu_vendor_hygon = 1;
257 } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
258 cpu_vendor_intel = 1;
259 } else {
260 EPRINTLN("Unknown cpu vendor \"%s\"", cpu_vendor);
261 error = -1;
263 return (error);