xmsr.c revision 276403
1153838Sdfr/*-
2153838Sdfr * Copyright (c) 2011 NetApp, Inc.
3153838Sdfr * All rights reserved.
4153838Sdfr *
5153838Sdfr * Redistribution and use in source and binary forms, with or without
6153838Sdfr * modification, are permitted provided that the following conditions
7153838Sdfr * are met:
8153838Sdfr * 1. Redistributions of source code must retain the above copyright
9153838Sdfr *    notice, this list of conditions and the following disclaimer.
10153838Sdfr * 2. Redistributions in binary form must reproduce the above copyright
11153838Sdfr *    notice, this list of conditions and the following disclaimer in the
12153838Sdfr *    documentation and/or other materials provided with the distribution.
13153838Sdfr *
14153838Sdfr * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15153838Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16153838Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17153838Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18153838Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19153838Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20153838Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21153838Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22153838Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23153838Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24153838Sdfr * SUCH DAMAGE.
25153838Sdfr *
26153838Sdfr * $FreeBSD: stable/10/usr.sbin/bhyve/xmsr.c 276403 2014-12-30 08:24:14Z neel $
27153838Sdfr */
28153838Sdfr
29153838Sdfr#include <sys/cdefs.h>
30203027Sgavin__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/xmsr.c 276403 2014-12-30 08:24:14Z neel $");
31206622Suqs
32153838Sdfr#include <sys/types.h>
33153838Sdfr
34153838Sdfr#include <machine/cpufunc.h>
35153838Sdfr#include <machine/vmm.h>
36153838Sdfr#include <machine/specialreg.h>
37153838Sdfr
38153838Sdfr#include <vmmapi.h>
39153838Sdfr
40153838Sdfr#include <stdio.h>
41153838Sdfr#include <stdlib.h>
42153838Sdfr#include <string.h>
43153838Sdfr
44153838Sdfr#include "xmsr.h"
45153838Sdfr
46153838Sdfrstatic int cpu_vendor_intel, cpu_vendor_amd;
47153838Sdfr
48153838Sdfrint
49153838Sdfremulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val)
50153838Sdfr{
51153838Sdfr
52153838Sdfr	if (cpu_vendor_intel) {
53153838Sdfr		switch (num) {
54153838Sdfr		case 0xd04:		/* Sandy Bridge uncore PMCs */
55153838Sdfr		case 0xc24:
56153838Sdfr			return (0);
57153838Sdfr		case MSR_BIOS_UPDT_TRIG:
58153838Sdfr			return (0);
59153838Sdfr		case MSR_BIOS_SIGN:
60153838Sdfr			return (0);
61153838Sdfr		default:
62153838Sdfr			break;
63153838Sdfr		}
64153838Sdfr	} else if (cpu_vendor_amd) {
65153838Sdfr		switch (num) {
66153838Sdfr		case MSR_HWCR:
67153838Sdfr			/*
68153838Sdfr			 * Ignore writes to hardware configuration MSR.
69153838Sdfr			 */
70153838Sdfr			return (0);
71153838Sdfr
72153838Sdfr		case MSR_NB_CFG1:
73153838Sdfr		case MSR_IC_CFG:
74153838Sdfr			return (0);	/* Ignore writes */
75153838Sdfr
76153838Sdfr		case MSR_PERFEVSEL0:
77153838Sdfr		case MSR_PERFEVSEL1:
78153838Sdfr		case MSR_PERFEVSEL2:
79153838Sdfr		case MSR_PERFEVSEL3:
80153838Sdfr			/* Ignore writes to the PerfEvtSel MSRs */
81153838Sdfr			return (0);
82153838Sdfr
83153838Sdfr		case MSR_K7_PERFCTR0:
84153838Sdfr		case MSR_K7_PERFCTR1:
85153838Sdfr		case MSR_K7_PERFCTR2:
86153838Sdfr		case MSR_K7_PERFCTR3:
87153838Sdfr			/* Ignore writes to the PerfCtr MSRs */
88153838Sdfr			return (0);
89153838Sdfr
90153838Sdfr		case MSR_P_STATE_CONTROL:
91153838Sdfr			/* Ignore write to change the P-state */
92153838Sdfr			return (0);
93153838Sdfr
94153838Sdfr		default:
95153838Sdfr			break;
96153838Sdfr		}
97153838Sdfr	}
98153838Sdfr	return (-1);
99153838Sdfr}
100153838Sdfr
101153838Sdfrint
102153838Sdfremulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val)
103236746Sjoel{
104153838Sdfr	int error = 0;
105153838Sdfr
106153838Sdfr	if (cpu_vendor_intel) {
107153838Sdfr		switch (num) {
108153838Sdfr		case MSR_BIOS_SIGN:
109153838Sdfr		case MSR_IA32_PLATFORM_ID:
110153838Sdfr		case MSR_PKG_ENERGY_STATUS:
111153838Sdfr		case MSR_PP0_ENERGY_STATUS:
112153838Sdfr		case MSR_PP1_ENERGY_STATUS:
113153838Sdfr		case MSR_DRAM_ENERGY_STATUS:
114153838Sdfr			*val = 0;
115236746Sjoel			break;
116153838Sdfr		case MSR_RAPL_POWER_UNIT:
117153838Sdfr			/*
118153838Sdfr			 * Use the default value documented in section
119153838Sdfr			 * "RAPL Interfaces" in Intel SDM vol3.
120153838Sdfr			 */
121153838Sdfr			*val = 0x000a1003;
122153838Sdfr			break;
123153838Sdfr		default:
124153838Sdfr			error = -1;
125153838Sdfr			break;
126153838Sdfr		}
127153838Sdfr	} else if (cpu_vendor_amd) {
128153838Sdfr		switch (num) {
129236746Sjoel		case MSR_BIOS_SIGN:
130153838Sdfr			*val = 0;
131153838Sdfr			break;
132153838Sdfr		case MSR_HWCR:
133153838Sdfr			/*
134153838Sdfr			 * Bios and Kernel Developer's Guides for AMD Families
135153838Sdfr			 * 12H, 14H, 15H and 16H.
136153838Sdfr			 */
137153838Sdfr			*val = 0x01000010;	/* Reset value */
138203027Sgavin			*val |= 1 << 9;		/* MONITOR/MWAIT disable */
139153838Sdfr			break;
140153838Sdfr
141153838Sdfr		case MSR_NB_CFG1:
142154811Sdfr		case MSR_IC_CFG:
143154811Sdfr			/*
144154811Sdfr			 * The reset value is processor family dependent so
145154811Sdfr			 * just return 0.
146154811Sdfr			 */
147154811Sdfr			*val = 0;
148154811Sdfr			break;
149154811Sdfr
150154811Sdfr		case MSR_PERFEVSEL0:
151154811Sdfr		case MSR_PERFEVSEL1:
152154811Sdfr		case MSR_PERFEVSEL2:
153154811Sdfr		case MSR_PERFEVSEL3:
154154811Sdfr			/*
155154811Sdfr			 * PerfEvtSel MSRs are not properly virtualized so just
156154811Sdfr			 * return zero.
157154811Sdfr			 */
158154811Sdfr			*val = 0;
159154811Sdfr			break;
160154811Sdfr
161154811Sdfr		case MSR_K7_PERFCTR0:
162154811Sdfr		case MSR_K7_PERFCTR1:
163154811Sdfr		case MSR_K7_PERFCTR2:
164154811Sdfr		case MSR_K7_PERFCTR3:
165154811Sdfr			/*
166154811Sdfr			 * PerfCtr MSRs are not properly virtualized so just
167154811Sdfr			 * return zero.
168			 */
169			*val = 0;
170			break;
171
172		case MSR_SMM_ADDR:
173		case MSR_SMM_MASK:
174			/*
175			 * Return the reset value defined in the AMD Bios and
176			 * Kernel Developer's Guide.
177			 */
178			*val = 0;
179			break;
180
181		case MSR_P_STATE_LIMIT:
182		case MSR_P_STATE_CONTROL:
183		case MSR_P_STATE_STATUS:
184		case MSR_P_STATE_CONFIG(0):	/* P0 configuration */
185			*val = 0;
186			break;
187
188		default:
189			error = -1;
190			break;
191		}
192	} else {
193		error = -1;
194	}
195	return (error);
196}
197
198int
199init_msr(void)
200{
201	int error;
202	u_int regs[4];
203	char cpu_vendor[13];
204
205	do_cpuid(0, regs);
206	((u_int *)&cpu_vendor)[0] = regs[1];
207	((u_int *)&cpu_vendor)[1] = regs[3];
208	((u_int *)&cpu_vendor)[2] = regs[2];
209	cpu_vendor[12] = '\0';
210
211	error = 0;
212	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
213		cpu_vendor_amd = 1;
214	} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
215		cpu_vendor_intel = 1;
216	} else {
217		fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor);
218		error = -1;
219	}
220	return (error);
221}
222