1bf21cd93STycho Nightingale /*-
2*32640292SAndy Fiddaman * SPDX-License-Identifier: BSD-2-Clause
34c87aefeSPatrick Mooney *
4bf21cd93STycho Nightingale * Copyright (c) 2011 NetApp, Inc.
5bf21cd93STycho Nightingale * All rights reserved.
6bf21cd93STycho Nightingale *
7bf21cd93STycho Nightingale * Redistribution and use in source and binary forms, with or without
8bf21cd93STycho Nightingale * modification, are permitted provided that the following conditions
9bf21cd93STycho Nightingale * are met:
10bf21cd93STycho Nightingale * 1. Redistributions of source code must retain the above copyright
11bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer.
12bf21cd93STycho Nightingale * 2. Redistributions in binary form must reproduce the above copyright
13bf21cd93STycho Nightingale * notice, this list of conditions and the following disclaimer in the
14bf21cd93STycho Nightingale * documentation and/or other materials provided with the distribution.
15bf21cd93STycho Nightingale *
16bf21cd93STycho Nightingale * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17bf21cd93STycho Nightingale * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18bf21cd93STycho Nightingale * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19bf21cd93STycho Nightingale * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20bf21cd93STycho Nightingale * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21bf21cd93STycho Nightingale * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22bf21cd93STycho Nightingale * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23bf21cd93STycho Nightingale * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24bf21cd93STycho Nightingale * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25bf21cd93STycho Nightingale * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bf21cd93STycho Nightingale * SUCH DAMAGE.
27bf21cd93STycho Nightingale */
28bf21cd93STycho Nightingale
29bf21cd93STycho Nightingale #include <sys/cdefs.h>
30bf21cd93STycho Nightingale
31bf21cd93STycho Nightingale #include <sys/types.h>
32bf21cd93STycho Nightingale
33bf21cd93STycho Nightingale #include <machine/cpufunc.h>
34bf21cd93STycho Nightingale #include <machine/vmm.h>
35bf21cd93STycho Nightingale #include <machine/specialreg.h>
36bf21cd93STycho Nightingale
37bf21cd93STycho Nightingale #include <vmmapi.h>
38bf21cd93STycho Nightingale
39bf21cd93STycho Nightingale #include <stdio.h>
40bf21cd93STycho Nightingale #include <stdlib.h>
41bf21cd93STycho Nightingale #include <string.h>
42bf21cd93STycho Nightingale
43154972afSPatrick Mooney #include "debug.h"
44bf21cd93STycho Nightingale #include "xmsr.h"
45bf21cd93STycho Nightingale
46154972afSPatrick Mooney static int cpu_vendor_intel, cpu_vendor_amd, cpu_vendor_hygon;
47bf21cd93STycho Nightingale
48bf21cd93STycho Nightingale int
emulate_wrmsr(struct vcpu * vcpu __unused,uint32_t num,uint64_t val __unused)49*32640292SAndy Fiddaman emulate_wrmsr(struct vcpu *vcpu __unused, uint32_t num, uint64_t val __unused)
50bf21cd93STycho Nightingale {
51bf21cd93STycho Nightingale
52bf21cd93STycho Nightingale if (cpu_vendor_intel) {
53bf21cd93STycho Nightingale switch (num) {
54bf21cd93STycho Nightingale #ifndef __FreeBSD__
55bf21cd93STycho Nightingale case MSR_PERFCTR0:
56bf21cd93STycho Nightingale case MSR_PERFCTR1:
57bf21cd93STycho Nightingale case MSR_EVNTSEL0:
58bf21cd93STycho Nightingale case MSR_EVNTSEL1:
59bf21cd93STycho Nightingale return (0);
60bf21cd93STycho Nightingale #endif
61bf21cd93STycho Nightingale case 0xd04: /* Sandy Bridge uncore PMCs */
62bf21cd93STycho Nightingale case 0xc24:
63bf21cd93STycho Nightingale return (0);
64bf21cd93STycho Nightingale case MSR_BIOS_UPDT_TRIG:
65bf21cd93STycho Nightingale return (0);
66bf21cd93STycho Nightingale case MSR_BIOS_SIGN:
67bf21cd93STycho Nightingale return (0);
68bf21cd93STycho Nightingale default:
69bf21cd93STycho Nightingale break;
70bf21cd93STycho Nightingale }
71154972afSPatrick Mooney } else if (cpu_vendor_amd || cpu_vendor_hygon) {
72bf21cd93STycho Nightingale switch (num) {
73bf21cd93STycho Nightingale case MSR_HWCR:
74bf21cd93STycho Nightingale /*
75bf21cd93STycho Nightingale * Ignore writes to hardware configuration MSR.
76bf21cd93STycho Nightingale */
77bf21cd93STycho Nightingale return (0);
78bf21cd93STycho Nightingale
79bf21cd93STycho Nightingale case MSR_NB_CFG1:
804c87aefeSPatrick Mooney case MSR_LS_CFG:
81bf21cd93STycho Nightingale case MSR_IC_CFG:
82bf21cd93STycho Nightingale return (0); /* Ignore writes */
83bf21cd93STycho Nightingale
84bf21cd93STycho Nightingale case MSR_PERFEVSEL0:
85bf21cd93STycho Nightingale case MSR_PERFEVSEL1:
86bf21cd93STycho Nightingale case MSR_PERFEVSEL2:
87bf21cd93STycho Nightingale case MSR_PERFEVSEL3:
88bf21cd93STycho Nightingale /* Ignore writes to the PerfEvtSel MSRs */
89bf21cd93STycho Nightingale return (0);
90bf21cd93STycho Nightingale
91bf21cd93STycho Nightingale case MSR_K7_PERFCTR0:
92bf21cd93STycho Nightingale case MSR_K7_PERFCTR1:
93bf21cd93STycho Nightingale case MSR_K7_PERFCTR2:
94bf21cd93STycho Nightingale case MSR_K7_PERFCTR3:
95bf21cd93STycho Nightingale /* Ignore writes to the PerfCtr MSRs */
96bf21cd93STycho Nightingale return (0);
97bf21cd93STycho Nightingale
98bf21cd93STycho Nightingale case MSR_P_STATE_CONTROL:
99bf21cd93STycho Nightingale /* Ignore write to change the P-state */
100bf21cd93STycho Nightingale return (0);
101bf21cd93STycho Nightingale
102bf21cd93STycho Nightingale default:
103bf21cd93STycho Nightingale break;
104bf21cd93STycho Nightingale }
105bf21cd93STycho Nightingale }
106bf21cd93STycho Nightingale return (-1);
107bf21cd93STycho Nightingale }
108bf21cd93STycho Nightingale
109bf21cd93STycho Nightingale int
emulate_rdmsr(struct vcpu * vcpu __unused,uint32_t num,uint64_t * val)110*32640292SAndy Fiddaman emulate_rdmsr(struct vcpu *vcpu __unused, uint32_t num, uint64_t *val)
111bf21cd93STycho Nightingale {
112bf21cd93STycho Nightingale int error = 0;
113bf21cd93STycho Nightingale
114bf21cd93STycho Nightingale if (cpu_vendor_intel) {
115bf21cd93STycho Nightingale switch (num) {
116bf21cd93STycho Nightingale case MSR_BIOS_SIGN:
117bf21cd93STycho Nightingale case MSR_IA32_PLATFORM_ID:
118bf21cd93STycho Nightingale case MSR_PKG_ENERGY_STATUS:
119bf21cd93STycho Nightingale case MSR_PP0_ENERGY_STATUS:
120bf21cd93STycho Nightingale case MSR_PP1_ENERGY_STATUS:
121bf21cd93STycho Nightingale case MSR_DRAM_ENERGY_STATUS:
12259d65d31SAndy Fiddaman case MSR_MISC_FEATURE_ENABLES:
123bf21cd93STycho Nightingale *val = 0;
124bf21cd93STycho Nightingale break;
125bf21cd93STycho Nightingale case MSR_RAPL_POWER_UNIT:
126bf21cd93STycho Nightingale /*
127bf21cd93STycho Nightingale * Use the default value documented in section
128bf21cd93STycho Nightingale * "RAPL Interfaces" in Intel SDM vol3.
129bf21cd93STycho Nightingale */
130bf21cd93STycho Nightingale *val = 0x000a1003;
131bf21cd93STycho Nightingale break;
132b0de25cbSAndy Fiddaman case MSR_IA32_FEATURE_CONTROL:
133b0de25cbSAndy Fiddaman /*
134b0de25cbSAndy Fiddaman * Windows guests check this MSR.
135b0de25cbSAndy Fiddaman * Set the lock bit to avoid writes
136b0de25cbSAndy Fiddaman * to this MSR.
137b0de25cbSAndy Fiddaman */
138b0de25cbSAndy Fiddaman *val = IA32_FEATURE_CONTROL_LOCK;
139b0de25cbSAndy Fiddaman break;
140bf21cd93STycho Nightingale default:
141bf21cd93STycho Nightingale error = -1;
142bf21cd93STycho Nightingale break;
143bf21cd93STycho Nightingale }
144154972afSPatrick Mooney } else if (cpu_vendor_amd || cpu_vendor_hygon) {
145bf21cd93STycho Nightingale switch (num) {
146bf21cd93STycho Nightingale case MSR_BIOS_SIGN:
147bf21cd93STycho Nightingale *val = 0;
148bf21cd93STycho Nightingale break;
149bf21cd93STycho Nightingale case MSR_HWCR:
150bf21cd93STycho Nightingale /*
151bf21cd93STycho Nightingale * Bios and Kernel Developer's Guides for AMD Families
152bf21cd93STycho Nightingale * 12H, 14H, 15H and 16H.
153bf21cd93STycho Nightingale */
154bf21cd93STycho Nightingale *val = 0x01000010; /* Reset value */
155bf21cd93STycho Nightingale *val |= 1 << 9; /* MONITOR/MWAIT disable */
156bf21cd93STycho Nightingale break;
157bf21cd93STycho Nightingale
158bf21cd93STycho Nightingale case MSR_NB_CFG1:
1594c87aefeSPatrick Mooney case MSR_LS_CFG:
160bf21cd93STycho Nightingale case MSR_IC_CFG:
161bf21cd93STycho Nightingale /*
162bf21cd93STycho Nightingale * The reset value is processor family dependent so
163bf21cd93STycho Nightingale * just return 0.
164bf21cd93STycho Nightingale */
165bf21cd93STycho Nightingale *val = 0;
166bf21cd93STycho Nightingale break;
167bf21cd93STycho Nightingale
168bf21cd93STycho Nightingale case MSR_PERFEVSEL0:
169bf21cd93STycho Nightingale case MSR_PERFEVSEL1:
170bf21cd93STycho Nightingale case MSR_PERFEVSEL2:
171bf21cd93STycho Nightingale case MSR_PERFEVSEL3:
172bf21cd93STycho Nightingale /*
173bf21cd93STycho Nightingale * PerfEvtSel MSRs are not properly virtualized so just
174bf21cd93STycho Nightingale * return zero.
175bf21cd93STycho Nightingale */
176bf21cd93STycho Nightingale *val = 0;
177bf21cd93STycho Nightingale break;
178bf21cd93STycho Nightingale
179bf21cd93STycho Nightingale case MSR_K7_PERFCTR0:
180bf21cd93STycho Nightingale case MSR_K7_PERFCTR1:
181bf21cd93STycho Nightingale case MSR_K7_PERFCTR2:
182bf21cd93STycho Nightingale case MSR_K7_PERFCTR3:
183bf21cd93STycho Nightingale /*
184bf21cd93STycho Nightingale * PerfCtr MSRs are not properly virtualized so just
185bf21cd93STycho Nightingale * return zero.
186bf21cd93STycho Nightingale */
187bf21cd93STycho Nightingale *val = 0;
188bf21cd93STycho Nightingale break;
189bf21cd93STycho Nightingale
190bf21cd93STycho Nightingale case MSR_SMM_ADDR:
191bf21cd93STycho Nightingale case MSR_SMM_MASK:
192bf21cd93STycho Nightingale /*
193bf21cd93STycho Nightingale * Return the reset value defined in the AMD Bios and
194bf21cd93STycho Nightingale * Kernel Developer's Guide.
195bf21cd93STycho Nightingale */
196bf21cd93STycho Nightingale *val = 0;
197bf21cd93STycho Nightingale break;
198bf21cd93STycho Nightingale
199bf21cd93STycho Nightingale case MSR_P_STATE_LIMIT:
200bf21cd93STycho Nightingale case MSR_P_STATE_CONTROL:
201bf21cd93STycho Nightingale case MSR_P_STATE_STATUS:
202bf21cd93STycho Nightingale case MSR_P_STATE_CONFIG(0): /* P0 configuration */
203bf21cd93STycho Nightingale *val = 0;
204bf21cd93STycho Nightingale break;
205bf21cd93STycho Nightingale
206bf21cd93STycho Nightingale /*
207bf21cd93STycho Nightingale * OpenBSD guests test bit 0 of this MSR to detect if the
208bf21cd93STycho Nightingale * workaround for erratum 721 is already applied.
2094c87aefeSPatrick Mooney * https://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf
210bf21cd93STycho Nightingale */
211bf21cd93STycho Nightingale case 0xC0011029:
212bf21cd93STycho Nightingale *val = 1;
213bf21cd93STycho Nightingale break;
214bf21cd93STycho Nightingale
2154c87aefeSPatrick Mooney #ifndef __FreeBSD__
2164c87aefeSPatrick Mooney case MSR_VM_CR:
2174c87aefeSPatrick Mooney /*
2184c87aefeSPatrick Mooney * We currently don't support nested virt.
2194c87aefeSPatrick Mooney * Windows seems to ignore the cpuid bits and reads this
2204c87aefeSPatrick Mooney * MSR anyways.
2214c87aefeSPatrick Mooney */
2224c87aefeSPatrick Mooney *val = VM_CR_SVMDIS;
2234c87aefeSPatrick Mooney break;
2244c87aefeSPatrick Mooney #endif
2254c87aefeSPatrick Mooney
226bf21cd93STycho Nightingale default:
227bf21cd93STycho Nightingale error = -1;
228bf21cd93STycho Nightingale break;
229bf21cd93STycho Nightingale }
230bf21cd93STycho Nightingale } else {
231bf21cd93STycho Nightingale error = -1;
232bf21cd93STycho Nightingale }
233bf21cd93STycho Nightingale return (error);
234bf21cd93STycho Nightingale }
235bf21cd93STycho Nightingale
236bf21cd93STycho Nightingale int
init_msr(void)237bf21cd93STycho Nightingale init_msr(void)
238bf21cd93STycho Nightingale {
239bf21cd93STycho Nightingale int error;
240bf21cd93STycho Nightingale u_int regs[4];
241bf21cd93STycho Nightingale char cpu_vendor[13];
242bf21cd93STycho Nightingale
243bf21cd93STycho Nightingale do_cpuid(0, regs);
244bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[0] = regs[1];
245bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[1] = regs[3];
246bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[2] = regs[2];
247bf21cd93STycho Nightingale cpu_vendor[12] = '\0';
248bf21cd93STycho Nightingale
249bf21cd93STycho Nightingale error = 0;
250bf21cd93STycho Nightingale if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
251bf21cd93STycho Nightingale cpu_vendor_amd = 1;
252154972afSPatrick Mooney } else if (strcmp(cpu_vendor, "HygonGenuine") == 0) {
253154972afSPatrick Mooney cpu_vendor_hygon = 1;
254bf21cd93STycho Nightingale } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
255bf21cd93STycho Nightingale cpu_vendor_intel = 1;
256bf21cd93STycho Nightingale } else {
257154972afSPatrick Mooney EPRINTLN("Unknown cpu vendor \"%s\"", cpu_vendor);
258bf21cd93STycho Nightingale error = -1;
259bf21cd93STycho Nightingale }
260bf21cd93STycho Nightingale return (error);
261bf21cd93STycho Nightingale }
262