1bf21cd93STycho Nightingale /*- 24c87aefeSPatrick Mooney * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * 284c87aefeSPatrick Mooney * $FreeBSD$ 29bf21cd93STycho Nightingale */ 30bf21cd93STycho Nightingale 31bf21cd93STycho Nightingale #include <sys/cdefs.h> 324c87aefeSPatrick Mooney __FBSDID("$FreeBSD$"); 33bf21cd93STycho Nightingale 34bf21cd93STycho Nightingale #include <sys/types.h> 35bf21cd93STycho Nightingale 36bf21cd93STycho Nightingale #include <machine/cpufunc.h> 37bf21cd93STycho Nightingale #include <machine/vmm.h> 38bf21cd93STycho Nightingale #include <machine/specialreg.h> 39bf21cd93STycho Nightingale 40bf21cd93STycho Nightingale #include <vmmapi.h> 41bf21cd93STycho Nightingale 42bf21cd93STycho Nightingale #include <stdio.h> 43bf21cd93STycho Nightingale #include <stdlib.h> 44bf21cd93STycho Nightingale #include <string.h> 45bf21cd93STycho Nightingale 46*154972afSPatrick Mooney #include "debug.h" 47bf21cd93STycho Nightingale #include "xmsr.h" 48bf21cd93STycho Nightingale 49*154972afSPatrick Mooney static int cpu_vendor_intel, cpu_vendor_amd, cpu_vendor_hygon; 50bf21cd93STycho Nightingale 51bf21cd93STycho Nightingale int 52bf21cd93STycho Nightingale emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val) 53bf21cd93STycho Nightingale { 54bf21cd93STycho Nightingale 55bf21cd93STycho Nightingale if (cpu_vendor_intel) { 56bf21cd93STycho Nightingale switch (num) { 57bf21cd93STycho Nightingale #ifndef __FreeBSD__ 58bf21cd93STycho Nightingale case MSR_PERFCTR0: 59bf21cd93STycho Nightingale case MSR_PERFCTR1: 60bf21cd93STycho Nightingale case MSR_EVNTSEL0: 61bf21cd93STycho Nightingale case MSR_EVNTSEL1: 62bf21cd93STycho Nightingale return (0); 63bf21cd93STycho Nightingale #endif 64bf21cd93STycho Nightingale case 0xd04: /* Sandy Bridge uncore PMCs */ 65bf21cd93STycho Nightingale case 0xc24: 66bf21cd93STycho Nightingale return (0); 67bf21cd93STycho Nightingale case MSR_BIOS_UPDT_TRIG: 68bf21cd93STycho Nightingale return (0); 69bf21cd93STycho Nightingale case MSR_BIOS_SIGN: 70bf21cd93STycho Nightingale return (0); 71bf21cd93STycho Nightingale default: 72bf21cd93STycho Nightingale break; 73bf21cd93STycho Nightingale } 74*154972afSPatrick Mooney } else if (cpu_vendor_amd || cpu_vendor_hygon) { 75bf21cd93STycho Nightingale switch (num) { 76bf21cd93STycho Nightingale case MSR_HWCR: 77bf21cd93STycho Nightingale /* 78bf21cd93STycho Nightingale * Ignore writes to hardware configuration MSR. 79bf21cd93STycho Nightingale */ 80bf21cd93STycho Nightingale return (0); 81bf21cd93STycho Nightingale 82bf21cd93STycho Nightingale case MSR_NB_CFG1: 834c87aefeSPatrick Mooney case MSR_LS_CFG: 84bf21cd93STycho Nightingale case MSR_IC_CFG: 85bf21cd93STycho Nightingale return (0); /* Ignore writes */ 86bf21cd93STycho Nightingale 87bf21cd93STycho Nightingale case MSR_PERFEVSEL0: 88bf21cd93STycho Nightingale case MSR_PERFEVSEL1: 89bf21cd93STycho Nightingale case MSR_PERFEVSEL2: 90bf21cd93STycho Nightingale case MSR_PERFEVSEL3: 91bf21cd93STycho Nightingale /* Ignore writes to the PerfEvtSel MSRs */ 92bf21cd93STycho Nightingale return (0); 93bf21cd93STycho Nightingale 94bf21cd93STycho Nightingale case MSR_K7_PERFCTR0: 95bf21cd93STycho Nightingale case MSR_K7_PERFCTR1: 96bf21cd93STycho Nightingale case MSR_K7_PERFCTR2: 97bf21cd93STycho Nightingale case MSR_K7_PERFCTR3: 98bf21cd93STycho Nightingale /* Ignore writes to the PerfCtr MSRs */ 99bf21cd93STycho Nightingale return (0); 100bf21cd93STycho Nightingale 101bf21cd93STycho Nightingale case MSR_P_STATE_CONTROL: 102bf21cd93STycho Nightingale /* Ignore write to change the P-state */ 103bf21cd93STycho Nightingale return (0); 104bf21cd93STycho Nightingale 105bf21cd93STycho Nightingale default: 106bf21cd93STycho Nightingale break; 107bf21cd93STycho Nightingale } 108bf21cd93STycho Nightingale } 109bf21cd93STycho Nightingale return (-1); 110bf21cd93STycho Nightingale } 111bf21cd93STycho Nightingale 112bf21cd93STycho Nightingale int 113bf21cd93STycho Nightingale emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) 114bf21cd93STycho Nightingale { 115bf21cd93STycho Nightingale int error = 0; 116bf21cd93STycho Nightingale 117bf21cd93STycho Nightingale if (cpu_vendor_intel) { 118bf21cd93STycho Nightingale switch (num) { 119bf21cd93STycho Nightingale case MSR_BIOS_SIGN: 120bf21cd93STycho Nightingale case MSR_IA32_PLATFORM_ID: 121bf21cd93STycho Nightingale case MSR_PKG_ENERGY_STATUS: 122bf21cd93STycho Nightingale case MSR_PP0_ENERGY_STATUS: 123bf21cd93STycho Nightingale case MSR_PP1_ENERGY_STATUS: 124bf21cd93STycho Nightingale case MSR_DRAM_ENERGY_STATUS: 125bf21cd93STycho Nightingale *val = 0; 126bf21cd93STycho Nightingale break; 127bf21cd93STycho Nightingale case MSR_RAPL_POWER_UNIT: 128bf21cd93STycho Nightingale /* 129bf21cd93STycho Nightingale * Use the default value documented in section 130bf21cd93STycho Nightingale * "RAPL Interfaces" in Intel SDM vol3. 131bf21cd93STycho Nightingale */ 132bf21cd93STycho Nightingale *val = 0x000a1003; 133bf21cd93STycho Nightingale break; 134bf21cd93STycho Nightingale default: 135bf21cd93STycho Nightingale error = -1; 136bf21cd93STycho Nightingale break; 137bf21cd93STycho Nightingale } 138*154972afSPatrick Mooney } else if (cpu_vendor_amd || cpu_vendor_hygon) { 139bf21cd93STycho Nightingale switch (num) { 140bf21cd93STycho Nightingale case MSR_BIOS_SIGN: 141bf21cd93STycho Nightingale *val = 0; 142bf21cd93STycho Nightingale break; 143bf21cd93STycho Nightingale case MSR_HWCR: 144bf21cd93STycho Nightingale /* 145bf21cd93STycho Nightingale * Bios and Kernel Developer's Guides for AMD Families 146bf21cd93STycho Nightingale * 12H, 14H, 15H and 16H. 147bf21cd93STycho Nightingale */ 148bf21cd93STycho Nightingale *val = 0x01000010; /* Reset value */ 149bf21cd93STycho Nightingale *val |= 1 << 9; /* MONITOR/MWAIT disable */ 150bf21cd93STycho Nightingale break; 151bf21cd93STycho Nightingale 152bf21cd93STycho Nightingale case MSR_NB_CFG1: 1534c87aefeSPatrick Mooney case MSR_LS_CFG: 154bf21cd93STycho Nightingale case MSR_IC_CFG: 155bf21cd93STycho Nightingale /* 156bf21cd93STycho Nightingale * The reset value is processor family dependent so 157bf21cd93STycho Nightingale * just return 0. 158bf21cd93STycho Nightingale */ 159bf21cd93STycho Nightingale *val = 0; 160bf21cd93STycho Nightingale break; 161bf21cd93STycho Nightingale 162bf21cd93STycho Nightingale case MSR_PERFEVSEL0: 163bf21cd93STycho Nightingale case MSR_PERFEVSEL1: 164bf21cd93STycho Nightingale case MSR_PERFEVSEL2: 165bf21cd93STycho Nightingale case MSR_PERFEVSEL3: 166bf21cd93STycho Nightingale /* 167bf21cd93STycho Nightingale * PerfEvtSel MSRs are not properly virtualized so just 168bf21cd93STycho Nightingale * return zero. 169bf21cd93STycho Nightingale */ 170bf21cd93STycho Nightingale *val = 0; 171bf21cd93STycho Nightingale break; 172bf21cd93STycho Nightingale 173bf21cd93STycho Nightingale case MSR_K7_PERFCTR0: 174bf21cd93STycho Nightingale case MSR_K7_PERFCTR1: 175bf21cd93STycho Nightingale case MSR_K7_PERFCTR2: 176bf21cd93STycho Nightingale case MSR_K7_PERFCTR3: 177bf21cd93STycho Nightingale /* 178bf21cd93STycho Nightingale * PerfCtr MSRs are not properly virtualized so just 179bf21cd93STycho Nightingale * return zero. 180bf21cd93STycho Nightingale */ 181bf21cd93STycho Nightingale *val = 0; 182bf21cd93STycho Nightingale break; 183bf21cd93STycho Nightingale 184bf21cd93STycho Nightingale case MSR_SMM_ADDR: 185bf21cd93STycho Nightingale case MSR_SMM_MASK: 186bf21cd93STycho Nightingale /* 187bf21cd93STycho Nightingale * Return the reset value defined in the AMD Bios and 188bf21cd93STycho Nightingale * Kernel Developer's Guide. 189bf21cd93STycho Nightingale */ 190bf21cd93STycho Nightingale *val = 0; 191bf21cd93STycho Nightingale break; 192bf21cd93STycho Nightingale 193bf21cd93STycho Nightingale case MSR_P_STATE_LIMIT: 194bf21cd93STycho Nightingale case MSR_P_STATE_CONTROL: 195bf21cd93STycho Nightingale case MSR_P_STATE_STATUS: 196bf21cd93STycho Nightingale case MSR_P_STATE_CONFIG(0): /* P0 configuration */ 197bf21cd93STycho Nightingale *val = 0; 198bf21cd93STycho Nightingale break; 199bf21cd93STycho Nightingale 200bf21cd93STycho Nightingale /* 201bf21cd93STycho Nightingale * OpenBSD guests test bit 0 of this MSR to detect if the 202bf21cd93STycho Nightingale * workaround for erratum 721 is already applied. 2034c87aefeSPatrick Mooney * https://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf 204bf21cd93STycho Nightingale */ 205bf21cd93STycho Nightingale case 0xC0011029: 206bf21cd93STycho Nightingale *val = 1; 207bf21cd93STycho Nightingale break; 208bf21cd93STycho Nightingale 2094c87aefeSPatrick Mooney #ifndef __FreeBSD__ 2104c87aefeSPatrick Mooney case MSR_VM_CR: 2114c87aefeSPatrick Mooney /* 2124c87aefeSPatrick Mooney * We currently don't support nested virt. 2134c87aefeSPatrick Mooney * Windows seems to ignore the cpuid bits and reads this 2144c87aefeSPatrick Mooney * MSR anyways. 2154c87aefeSPatrick Mooney */ 2164c87aefeSPatrick Mooney *val = VM_CR_SVMDIS; 2174c87aefeSPatrick Mooney break; 2184c87aefeSPatrick Mooney #endif 2194c87aefeSPatrick Mooney 220bf21cd93STycho Nightingale default: 221bf21cd93STycho Nightingale error = -1; 222bf21cd93STycho Nightingale break; 223bf21cd93STycho Nightingale } 224bf21cd93STycho Nightingale } else { 225bf21cd93STycho Nightingale error = -1; 226bf21cd93STycho Nightingale } 227bf21cd93STycho Nightingale return (error); 228bf21cd93STycho Nightingale } 229bf21cd93STycho Nightingale 230bf21cd93STycho Nightingale int 231bf21cd93STycho Nightingale init_msr(void) 232bf21cd93STycho Nightingale { 233bf21cd93STycho Nightingale int error; 234bf21cd93STycho Nightingale u_int regs[4]; 235bf21cd93STycho Nightingale char cpu_vendor[13]; 236bf21cd93STycho Nightingale 237bf21cd93STycho Nightingale do_cpuid(0, regs); 238bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[0] = regs[1]; 239bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[1] = regs[3]; 240bf21cd93STycho Nightingale ((u_int *)&cpu_vendor)[2] = regs[2]; 241bf21cd93STycho Nightingale cpu_vendor[12] = '\0'; 242bf21cd93STycho Nightingale 243bf21cd93STycho Nightingale error = 0; 244bf21cd93STycho Nightingale if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 245bf21cd93STycho Nightingale cpu_vendor_amd = 1; 246*154972afSPatrick Mooney } else if (strcmp(cpu_vendor, "HygonGenuine") == 0) { 247*154972afSPatrick Mooney cpu_vendor_hygon = 1; 248bf21cd93STycho Nightingale } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { 249bf21cd93STycho Nightingale cpu_vendor_intel = 1; 250bf21cd93STycho Nightingale } else { 251*154972afSPatrick Mooney EPRINTLN("Unknown cpu vendor \"%s\"", cpu_vendor); 252bf21cd93STycho Nightingale error = -1; 253bf21cd93STycho Nightingale } 254bf21cd93STycho Nightingale return (error); 255bf21cd93STycho Nightingale } 256