xref: /illumos-gate/usr/src/cmd/bhyve/xmsr.c (revision 32640292)
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