1/*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: releng/10.3/usr.sbin/bhyve/xmsr.c 284894 2015-06-27 22:48:22Z neel $ 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: releng/10.3/usr.sbin/bhyve/xmsr.c 284894 2015-06-27 22:48:22Z neel $"); 31 32#include <sys/types.h> 33 34#include <machine/cpufunc.h> 35#include <machine/vmm.h> 36#include <machine/specialreg.h> 37 38#include <vmmapi.h> 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43 44#include "xmsr.h" 45 46static int cpu_vendor_intel, cpu_vendor_amd; 47 48int 49emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val) 50{ 51 52 if (cpu_vendor_intel) { 53 switch (num) { 54 case 0xd04: /* Sandy Bridge uncore PMCs */ 55 case 0xc24: 56 return (0); 57 case MSR_BIOS_UPDT_TRIG: 58 return (0); 59 case MSR_BIOS_SIGN: 60 return (0); 61 default: 62 break; 63 } 64 } else if (cpu_vendor_amd) { 65 switch (num) { 66 case MSR_HWCR: 67 /* 68 * Ignore writes to hardware configuration MSR. 69 */ 70 return (0); 71 72 case MSR_NB_CFG1: 73 case MSR_IC_CFG: 74 return (0); /* Ignore writes */ 75 76 case MSR_PERFEVSEL0: 77 case MSR_PERFEVSEL1: 78 case MSR_PERFEVSEL2: 79 case MSR_PERFEVSEL3: 80 /* Ignore writes to the PerfEvtSel MSRs */ 81 return (0); 82 83 case MSR_K7_PERFCTR0: 84 case MSR_K7_PERFCTR1: 85 case MSR_K7_PERFCTR2: 86 case MSR_K7_PERFCTR3: 87 /* Ignore writes to the PerfCtr MSRs */ 88 return (0); 89 90 case MSR_P_STATE_CONTROL: 91 /* Ignore write to change the P-state */ 92 return (0); 93 94 default: 95 break; 96 } 97 } 98 return (-1); 99} 100 101int 102emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) 103{ 104 int error = 0; 105 106 if (cpu_vendor_intel) { 107 switch (num) { 108 case MSR_BIOS_SIGN: 109 case MSR_IA32_PLATFORM_ID: 110 case MSR_PKG_ENERGY_STATUS: 111 case MSR_PP0_ENERGY_STATUS: 112 case MSR_PP1_ENERGY_STATUS: 113 case MSR_DRAM_ENERGY_STATUS: 114 *val = 0; 115 break; 116 case MSR_RAPL_POWER_UNIT: 117 /* 118 * Use the default value documented in section 119 * "RAPL Interfaces" in Intel SDM vol3. 120 */ 121 *val = 0x000a1003; 122 break; 123 default: 124 error = -1; 125 break; 126 } 127 } else if (cpu_vendor_amd) { 128 switch (num) { 129 case MSR_BIOS_SIGN: 130 *val = 0; 131 break; 132 case MSR_HWCR: 133 /* 134 * Bios and Kernel Developer's Guides for AMD Families 135 * 12H, 14H, 15H and 16H. 136 */ 137 *val = 0x01000010; /* Reset value */ 138 *val |= 1 << 9; /* MONITOR/MWAIT disable */ 139 break; 140 141 case MSR_NB_CFG1: 142 case MSR_IC_CFG: 143 /* 144 * The reset value is processor family dependent so 145 * just return 0. 146 */ 147 *val = 0; 148 break; 149 150 case MSR_PERFEVSEL0: 151 case MSR_PERFEVSEL1: 152 case MSR_PERFEVSEL2: 153 case MSR_PERFEVSEL3: 154 /* 155 * PerfEvtSel MSRs are not properly virtualized so just 156 * return zero. 157 */ 158 *val = 0; 159 break; 160 161 case MSR_K7_PERFCTR0: 162 case MSR_K7_PERFCTR1: 163 case MSR_K7_PERFCTR2: 164 case MSR_K7_PERFCTR3: 165 /* 166 * PerfCtr MSRs are not properly virtualized so just 167 * 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 /* 189 * OpenBSD guests test bit 0 of this MSR to detect if the 190 * workaround for erratum 721 is already applied. 191 * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf 192 */ 193 case 0xC0011029: 194 *val = 1; 195 break; 196 197 default: 198 error = -1; 199 break; 200 } 201 } else { 202 error = -1; 203 } 204 return (error); 205} 206 207int 208init_msr(void) 209{ 210 int error; 211 u_int regs[4]; 212 char cpu_vendor[13]; 213 214 do_cpuid(0, regs); 215 ((u_int *)&cpu_vendor)[0] = regs[1]; 216 ((u_int *)&cpu_vendor)[1] = regs[3]; 217 ((u_int *)&cpu_vendor)[2] = regs[2]; 218 cpu_vendor[12] = '\0'; 219 220 error = 0; 221 if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 222 cpu_vendor_amd = 1; 223 } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 224 cpu_vendor_intel = 1; 225 } else { 226 fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor); 227 error = -1; 228 } 229 return (error); 230} 231