1221828Sgrehan/*- 2221828Sgrehan * Copyright (c) 2011 NetApp, Inc. 3221828Sgrehan * All rights reserved. 4221828Sgrehan * 5221828Sgrehan * Redistribution and use in source and binary forms, with or without 6221828Sgrehan * modification, are permitted provided that the following conditions 7221828Sgrehan * are met: 8221828Sgrehan * 1. Redistributions of source code must retain the above copyright 9221828Sgrehan * notice, this list of conditions and the following disclaimer. 10221828Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 11221828Sgrehan * notice, this list of conditions and the following disclaimer in the 12221828Sgrehan * documentation and/or other materials provided with the distribution. 13221828Sgrehan * 14221828Sgrehan * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15221828Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16221828Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17221828Sgrehan * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18221828Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19221828Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20221828Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21221828Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22221828Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23221828Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24221828Sgrehan * SUCH DAMAGE. 25221828Sgrehan * 26221828Sgrehan * $FreeBSD: releng/10.3/usr.sbin/bhyve/xmsr.c 284894 2015-06-27 22:48:22Z neel $ 27221828Sgrehan */ 28221828Sgrehan 29221828Sgrehan#include <sys/cdefs.h> 30221828Sgrehan__FBSDID("$FreeBSD: releng/10.3/usr.sbin/bhyve/xmsr.c 284894 2015-06-27 22:48:22Z neel $"); 31221828Sgrehan 32240912Sneel#include <sys/types.h> 33221828Sgrehan 34276349Sneel#include <machine/cpufunc.h> 35221828Sgrehan#include <machine/vmm.h> 36276349Sneel#include <machine/specialreg.h> 37276349Sneel 38221828Sgrehan#include <vmmapi.h> 39221828Sgrehan 40240912Sneel#include <stdio.h> 41240912Sneel#include <stdlib.h> 42276349Sneel#include <string.h> 43240912Sneel 44221828Sgrehan#include "xmsr.h" 45221828Sgrehan 46276349Sneelstatic int cpu_vendor_intel, cpu_vendor_amd; 47276349Sneel 48221828Sgrehanint 49276403Sneelemulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val) 50221828Sgrehan{ 51221828Sgrehan 52276349Sneel if (cpu_vendor_intel) { 53276403Sneel switch (num) { 54276349Sneel case 0xd04: /* Sandy Bridge uncore PMCs */ 55276349Sneel case 0xc24: 56276349Sneel return (0); 57276349Sneel case MSR_BIOS_UPDT_TRIG: 58276349Sneel return (0); 59276349Sneel case MSR_BIOS_SIGN: 60276349Sneel return (0); 61276349Sneel default: 62276349Sneel break; 63276349Sneel } 64276403Sneel } else if (cpu_vendor_amd) { 65276403Sneel switch (num) { 66276403Sneel case MSR_HWCR: 67276403Sneel /* 68276403Sneel * Ignore writes to hardware configuration MSR. 69276403Sneel */ 70276403Sneel return (0); 71276403Sneel 72276403Sneel case MSR_NB_CFG1: 73276403Sneel case MSR_IC_CFG: 74276403Sneel return (0); /* Ignore writes */ 75276403Sneel 76276403Sneel case MSR_PERFEVSEL0: 77276403Sneel case MSR_PERFEVSEL1: 78276403Sneel case MSR_PERFEVSEL2: 79276403Sneel case MSR_PERFEVSEL3: 80276403Sneel /* Ignore writes to the PerfEvtSel MSRs */ 81276403Sneel return (0); 82276403Sneel 83276403Sneel case MSR_K7_PERFCTR0: 84276403Sneel case MSR_K7_PERFCTR1: 85276403Sneel case MSR_K7_PERFCTR2: 86276403Sneel case MSR_K7_PERFCTR3: 87276403Sneel /* Ignore writes to the PerfCtr MSRs */ 88276403Sneel return (0); 89276403Sneel 90276403Sneel case MSR_P_STATE_CONTROL: 91276403Sneel /* Ignore write to change the P-state */ 92276403Sneel return (0); 93276403Sneel 94276403Sneel default: 95276403Sneel break; 96276403Sneel } 97264273Sjhb } 98264273Sjhb return (-1); 99221828Sgrehan} 100264273Sjhb 101264273Sjhbint 102276349Sneelemulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) 103264273Sjhb{ 104276349Sneel int error = 0; 105264273Sjhb 106276349Sneel if (cpu_vendor_intel) { 107276349Sneel switch (num) { 108276349Sneel case MSR_BIOS_SIGN: 109276349Sneel case MSR_IA32_PLATFORM_ID: 110276349Sneel case MSR_PKG_ENERGY_STATUS: 111276349Sneel case MSR_PP0_ENERGY_STATUS: 112276349Sneel case MSR_PP1_ENERGY_STATUS: 113276349Sneel case MSR_DRAM_ENERGY_STATUS: 114276349Sneel *val = 0; 115276349Sneel break; 116276349Sneel case MSR_RAPL_POWER_UNIT: 117276349Sneel /* 118276349Sneel * Use the default value documented in section 119276349Sneel * "RAPL Interfaces" in Intel SDM vol3. 120276349Sneel */ 121276349Sneel *val = 0x000a1003; 122276349Sneel break; 123276349Sneel default: 124276349Sneel error = -1; 125276349Sneel break; 126276349Sneel } 127276403Sneel } else if (cpu_vendor_amd) { 128276403Sneel switch (num) { 129276403Sneel case MSR_BIOS_SIGN: 130276403Sneel *val = 0; 131276403Sneel break; 132276403Sneel case MSR_HWCR: 133276403Sneel /* 134276403Sneel * Bios and Kernel Developer's Guides for AMD Families 135276403Sneel * 12H, 14H, 15H and 16H. 136276403Sneel */ 137276403Sneel *val = 0x01000010; /* Reset value */ 138276403Sneel *val |= 1 << 9; /* MONITOR/MWAIT disable */ 139276403Sneel break; 140276403Sneel 141276403Sneel case MSR_NB_CFG1: 142276403Sneel case MSR_IC_CFG: 143276403Sneel /* 144276403Sneel * The reset value is processor family dependent so 145276403Sneel * just return 0. 146276403Sneel */ 147276403Sneel *val = 0; 148276403Sneel break; 149276403Sneel 150276403Sneel case MSR_PERFEVSEL0: 151276403Sneel case MSR_PERFEVSEL1: 152276403Sneel case MSR_PERFEVSEL2: 153276403Sneel case MSR_PERFEVSEL3: 154276403Sneel /* 155276403Sneel * PerfEvtSel MSRs are not properly virtualized so just 156276403Sneel * return zero. 157276403Sneel */ 158276403Sneel *val = 0; 159276403Sneel break; 160276403Sneel 161276403Sneel case MSR_K7_PERFCTR0: 162276403Sneel case MSR_K7_PERFCTR1: 163276403Sneel case MSR_K7_PERFCTR2: 164276403Sneel case MSR_K7_PERFCTR3: 165276403Sneel /* 166276403Sneel * PerfCtr MSRs are not properly virtualized so just 167276403Sneel * return zero. 168276403Sneel */ 169276403Sneel *val = 0; 170276403Sneel break; 171276403Sneel 172276403Sneel case MSR_SMM_ADDR: 173276403Sneel case MSR_SMM_MASK: 174276403Sneel /* 175276403Sneel * Return the reset value defined in the AMD Bios and 176276403Sneel * Kernel Developer's Guide. 177276403Sneel */ 178276403Sneel *val = 0; 179276403Sneel break; 180276403Sneel 181276403Sneel case MSR_P_STATE_LIMIT: 182276403Sneel case MSR_P_STATE_CONTROL: 183276403Sneel case MSR_P_STATE_STATUS: 184276403Sneel case MSR_P_STATE_CONFIG(0): /* P0 configuration */ 185276403Sneel *val = 0; 186276403Sneel break; 187276403Sneel 188284894Sneel /* 189284894Sneel * OpenBSD guests test bit 0 of this MSR to detect if the 190284894Sneel * workaround for erratum 721 is already applied. 191284894Sneel * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf 192284894Sneel */ 193284894Sneel case 0xC0011029: 194284894Sneel *val = 1; 195284894Sneel break; 196284894Sneel 197276403Sneel default: 198276403Sneel error = -1; 199276403Sneel break; 200276403Sneel } 201276403Sneel } else { 202276403Sneel error = -1; 203276349Sneel } 204276349Sneel return (error); 205264273Sjhb} 206276349Sneel 207276349Sneelint 208276349Sneelinit_msr(void) 209276349Sneel{ 210276349Sneel int error; 211276349Sneel u_int regs[4]; 212276349Sneel char cpu_vendor[13]; 213276349Sneel 214276349Sneel do_cpuid(0, regs); 215276349Sneel ((u_int *)&cpu_vendor)[0] = regs[1]; 216276349Sneel ((u_int *)&cpu_vendor)[1] = regs[3]; 217276349Sneel ((u_int *)&cpu_vendor)[2] = regs[2]; 218276349Sneel cpu_vendor[12] = '\0'; 219276349Sneel 220276349Sneel error = 0; 221276349Sneel if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 222276349Sneel cpu_vendor_amd = 1; 223276349Sneel } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 224276349Sneel cpu_vendor_intel = 1; 225276349Sneel } else { 226276349Sneel fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor); 227276349Sneel error = -1; 228276349Sneel } 229276349Sneel return (error); 230276349Sneel} 231