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/11.0/usr.sbin/bhyve/xmsr.c 279227 2015-02-24 05:15:40Z neel $ 27221828Sgrehan */ 28221828Sgrehan 29221828Sgrehan#include <sys/cdefs.h> 30221828Sgrehan__FBSDID("$FreeBSD: releng/11.0/usr.sbin/bhyve/xmsr.c 279227 2015-02-24 05:15:40Z neel $"); 31221828Sgrehan 32240912Sneel#include <sys/types.h> 33221828Sgrehan 34271888Sneel#include <machine/cpufunc.h> 35221828Sgrehan#include <machine/vmm.h> 36271888Sneel#include <machine/specialreg.h> 37271888Sneel 38221828Sgrehan#include <vmmapi.h> 39221828Sgrehan 40240912Sneel#include <stdio.h> 41240912Sneel#include <stdlib.h> 42271888Sneel#include <string.h> 43240912Sneel 44221828Sgrehan#include "xmsr.h" 45221828Sgrehan 46271888Sneelstatic int cpu_vendor_intel, cpu_vendor_amd; 47271888Sneel 48221828Sgrehanint 49273375Sneelemulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val) 50221828Sgrehan{ 51221828Sgrehan 52271888Sneel if (cpu_vendor_intel) { 53273375Sneel switch (num) { 54271888Sneel case 0xd04: /* Sandy Bridge uncore PMCs */ 55271888Sneel case 0xc24: 56271888Sneel return (0); 57271888Sneel case MSR_BIOS_UPDT_TRIG: 58271888Sneel return (0); 59271888Sneel case MSR_BIOS_SIGN: 60271888Sneel return (0); 61271888Sneel default: 62271888Sneel break; 63271888Sneel } 64273375Sneel } else if (cpu_vendor_amd) { 65273375Sneel switch (num) { 66273375Sneel case MSR_HWCR: 67273375Sneel /* 68273375Sneel * Ignore writes to hardware configuration MSR. 69273375Sneel */ 70273375Sneel return (0); 71273375Sneel 72273375Sneel case MSR_NB_CFG1: 73273375Sneel case MSR_IC_CFG: 74273375Sneel return (0); /* Ignore writes */ 75273375Sneel 76273375Sneel case MSR_PERFEVSEL0: 77273375Sneel case MSR_PERFEVSEL1: 78273375Sneel case MSR_PERFEVSEL2: 79273375Sneel case MSR_PERFEVSEL3: 80273375Sneel /* Ignore writes to the PerfEvtSel MSRs */ 81273375Sneel return (0); 82273375Sneel 83273375Sneel case MSR_K7_PERFCTR0: 84273375Sneel case MSR_K7_PERFCTR1: 85273375Sneel case MSR_K7_PERFCTR2: 86273375Sneel case MSR_K7_PERFCTR3: 87273375Sneel /* Ignore writes to the PerfCtr MSRs */ 88273375Sneel return (0); 89273375Sneel 90273375Sneel case MSR_P_STATE_CONTROL: 91273375Sneel /* Ignore write to change the P-state */ 92273375Sneel return (0); 93273375Sneel 94273375Sneel default: 95273375Sneel break; 96273375Sneel } 97259635Sneel } 98259635Sneel return (-1); 99221828Sgrehan} 100259635Sneel 101259635Sneelint 102271888Sneelemulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) 103259635Sneel{ 104271888Sneel int error = 0; 105259635Sneel 106271888Sneel if (cpu_vendor_intel) { 107271888Sneel switch (num) { 108271888Sneel case MSR_BIOS_SIGN: 109271888Sneel case MSR_IA32_PLATFORM_ID: 110271888Sneel case MSR_PKG_ENERGY_STATUS: 111271888Sneel case MSR_PP0_ENERGY_STATUS: 112271888Sneel case MSR_PP1_ENERGY_STATUS: 113271888Sneel case MSR_DRAM_ENERGY_STATUS: 114271888Sneel *val = 0; 115271888Sneel break; 116272839Sneel case MSR_RAPL_POWER_UNIT: 117272839Sneel /* 118272839Sneel * Use the default value documented in section 119272839Sneel * "RAPL Interfaces" in Intel SDM vol3. 120272839Sneel */ 121272839Sneel *val = 0x000a1003; 122272839Sneel break; 123271888Sneel default: 124271888Sneel error = -1; 125271888Sneel break; 126271888Sneel } 127273375Sneel } else if (cpu_vendor_amd) { 128273375Sneel switch (num) { 129273375Sneel case MSR_BIOS_SIGN: 130273375Sneel *val = 0; 131273375Sneel break; 132273375Sneel case MSR_HWCR: 133273375Sneel /* 134273375Sneel * Bios and Kernel Developer's Guides for AMD Families 135273375Sneel * 12H, 14H, 15H and 16H. 136273375Sneel */ 137273375Sneel *val = 0x01000010; /* Reset value */ 138273375Sneel *val |= 1 << 9; /* MONITOR/MWAIT disable */ 139273375Sneel break; 140273375Sneel 141273375Sneel case MSR_NB_CFG1: 142273375Sneel case MSR_IC_CFG: 143273375Sneel /* 144273375Sneel * The reset value is processor family dependent so 145273375Sneel * just return 0. 146273375Sneel */ 147273375Sneel *val = 0; 148273375Sneel break; 149273375Sneel 150273375Sneel case MSR_PERFEVSEL0: 151273375Sneel case MSR_PERFEVSEL1: 152273375Sneel case MSR_PERFEVSEL2: 153273375Sneel case MSR_PERFEVSEL3: 154273375Sneel /* 155273375Sneel * PerfEvtSel MSRs are not properly virtualized so just 156273375Sneel * return zero. 157273375Sneel */ 158273375Sneel *val = 0; 159273375Sneel break; 160273375Sneel 161273375Sneel case MSR_K7_PERFCTR0: 162273375Sneel case MSR_K7_PERFCTR1: 163273375Sneel case MSR_K7_PERFCTR2: 164273375Sneel case MSR_K7_PERFCTR3: 165273375Sneel /* 166273375Sneel * PerfCtr MSRs are not properly virtualized so just 167273375Sneel * return zero. 168273375Sneel */ 169273375Sneel *val = 0; 170273375Sneel break; 171273375Sneel 172273375Sneel case MSR_SMM_ADDR: 173273375Sneel case MSR_SMM_MASK: 174273375Sneel /* 175273375Sneel * Return the reset value defined in the AMD Bios and 176273375Sneel * Kernel Developer's Guide. 177273375Sneel */ 178273375Sneel *val = 0; 179273375Sneel break; 180273375Sneel 181273375Sneel case MSR_P_STATE_LIMIT: 182273375Sneel case MSR_P_STATE_CONTROL: 183273375Sneel case MSR_P_STATE_STATUS: 184273375Sneel case MSR_P_STATE_CONFIG(0): /* P0 configuration */ 185273375Sneel *val = 0; 186273375Sneel break; 187273375Sneel 188279227Sneel /* 189279227Sneel * OpenBSD guests test bit 0 of this MSR to detect if the 190279227Sneel * workaround for erratum 721 is already applied. 191279227Sneel * http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf 192279227Sneel */ 193279227Sneel case 0xC0011029: 194279227Sneel *val = 1; 195279227Sneel break; 196279227Sneel 197273375Sneel default: 198273375Sneel error = -1; 199273375Sneel break; 200273375Sneel } 201273375Sneel } else { 202273375Sneel error = -1; 203271888Sneel } 204271888Sneel return (error); 205259635Sneel} 206271888Sneel 207271888Sneelint 208271888Sneelinit_msr(void) 209271888Sneel{ 210271888Sneel int error; 211271888Sneel u_int regs[4]; 212271888Sneel char cpu_vendor[13]; 213271888Sneel 214271888Sneel do_cpuid(0, regs); 215271888Sneel ((u_int *)&cpu_vendor)[0] = regs[1]; 216271888Sneel ((u_int *)&cpu_vendor)[1] = regs[3]; 217271888Sneel ((u_int *)&cpu_vendor)[2] = regs[2]; 218271888Sneel cpu_vendor[12] = '\0'; 219271888Sneel 220271888Sneel error = 0; 221271888Sneel if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 222271888Sneel cpu_vendor_amd = 1; 223271888Sneel } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 224271888Sneel cpu_vendor_intel = 1; 225271888Sneel } else { 226271888Sneel fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor); 227271888Sneel error = -1; 228271888Sneel } 229271888Sneel return (error); 230271888Sneel} 231