18f02c5e4SNeel Natu /*- 2ebc3c37cSMarcelo Araujo * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3ebc3c37cSMarcelo Araujo * 48f02c5e4SNeel Natu * Copyright (c) 2014, Neel Natu (neel@freebsd.org) 58f02c5e4SNeel Natu * All rights reserved. 68f02c5e4SNeel Natu * 78f02c5e4SNeel Natu * Redistribution and use in source and binary forms, with or without 88f02c5e4SNeel Natu * modification, are permitted provided that the following conditions 98f02c5e4SNeel Natu * are met: 108f02c5e4SNeel Natu * 1. Redistributions of source code must retain the above copyright 118f02c5e4SNeel Natu * notice unmodified, this list of conditions, and the following 128f02c5e4SNeel Natu * disclaimer. 138f02c5e4SNeel Natu * 2. Redistributions in binary form must reproduce the above copyright 148f02c5e4SNeel Natu * notice, this list of conditions and the following disclaimer in the 158f02c5e4SNeel Natu * documentation and/or other materials provided with the distribution. 168f02c5e4SNeel Natu * 178f02c5e4SNeel Natu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 188f02c5e4SNeel Natu * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 198f02c5e4SNeel Natu * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 208f02c5e4SNeel Natu * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 218f02c5e4SNeel Natu * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 228f02c5e4SNeel Natu * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238f02c5e4SNeel Natu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248f02c5e4SNeel Natu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258f02c5e4SNeel Natu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 268f02c5e4SNeel Natu * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278f02c5e4SNeel Natu */ 288f02c5e4SNeel Natu 298f02c5e4SNeel Natu #include <sys/cdefs.h> 308f02c5e4SNeel Natu __FBSDID("$FreeBSD$"); 318f02c5e4SNeel Natu 32483d953aSJohn Baldwin #include "opt_bhyve_snapshot.h" 33483d953aSJohn Baldwin 347d786ee2SNeel Natu #include <sys/param.h> 358f02c5e4SNeel Natu #include <sys/errno.h> 367d786ee2SNeel Natu #include <sys/systm.h> 378f02c5e4SNeel Natu 388f02c5e4SNeel Natu #include <machine/cpufunc.h> 398f02c5e4SNeel Natu #include <machine/specialreg.h> 407d786ee2SNeel Natu #include <machine/vmm.h> 418f02c5e4SNeel Natu 427d786ee2SNeel Natu #include "svm.h" 437d786ee2SNeel Natu #include "vmcb.h" 447d786ee2SNeel Natu #include "svm_softc.h" 458f02c5e4SNeel Natu #include "svm_msr.h" 468f02c5e4SNeel Natu 478f02c5e4SNeel Natu #ifndef MSR_AMDK8_IPM 488f02c5e4SNeel Natu #define MSR_AMDK8_IPM 0xc0010055 498f02c5e4SNeel Natu #endif 508f02c5e4SNeel Natu 518f02c5e4SNeel Natu enum { 528f02c5e4SNeel Natu IDX_MSR_LSTAR, 538f02c5e4SNeel Natu IDX_MSR_CSTAR, 548f02c5e4SNeel Natu IDX_MSR_STAR, 558f02c5e4SNeel Natu IDX_MSR_SF_MASK, 568f02c5e4SNeel Natu HOST_MSR_NUM /* must be the last enumeration */ 578f02c5e4SNeel Natu }; 588f02c5e4SNeel Natu 598f02c5e4SNeel Natu static uint64_t host_msrs[HOST_MSR_NUM]; 608f02c5e4SNeel Natu 618f02c5e4SNeel Natu void 628f02c5e4SNeel Natu svm_msr_init(void) 638f02c5e4SNeel Natu { 648f02c5e4SNeel Natu /* 658f02c5e4SNeel Natu * It is safe to cache the values of the following MSRs because they 668f02c5e4SNeel Natu * don't change based on curcpu, curproc or curthread. 678f02c5e4SNeel Natu */ 688f02c5e4SNeel Natu host_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); 698f02c5e4SNeel Natu host_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); 708f02c5e4SNeel Natu host_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); 718f02c5e4SNeel Natu host_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); 728f02c5e4SNeel Natu } 738f02c5e4SNeel Natu 748f02c5e4SNeel Natu void 751aa51504SJohn Baldwin svm_msr_guest_init(struct svm_softc *sc, struct svm_vcpu *vcpu) 768f02c5e4SNeel Natu { 778f02c5e4SNeel Natu /* 788f02c5e4SNeel Natu * All the MSRs accessible to the guest are either saved/restored by 798f02c5e4SNeel Natu * hardware on every #VMEXIT/VMRUN (e.g., G_PAT) or are saved/restored 808f02c5e4SNeel Natu * by VMSAVE/VMLOAD (e.g., MSR_GSBASE). 818f02c5e4SNeel Natu * 828f02c5e4SNeel Natu * There are no guest MSRs that are saved/restored "by hand" so nothing 838f02c5e4SNeel Natu * more to do here. 848f02c5e4SNeel Natu */ 858f02c5e4SNeel Natu return; 868f02c5e4SNeel Natu } 878f02c5e4SNeel Natu 888f02c5e4SNeel Natu void 89*80cb5d84SJohn Baldwin svm_msr_guest_enter(struct svm_vcpu *vcpu) 908f02c5e4SNeel Natu { 918f02c5e4SNeel Natu /* 928f02c5e4SNeel Natu * Save host MSRs (if any) and restore guest MSRs (if any). 938f02c5e4SNeel Natu */ 948f02c5e4SNeel Natu } 958f02c5e4SNeel Natu 968f02c5e4SNeel Natu void 97*80cb5d84SJohn Baldwin svm_msr_guest_exit(struct svm_vcpu *vcpu) 988f02c5e4SNeel Natu { 998f02c5e4SNeel Natu /* 1008f02c5e4SNeel Natu * Save guest MSRs (if any) and restore host MSRs. 1018f02c5e4SNeel Natu */ 1028f02c5e4SNeel Natu wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); 1038f02c5e4SNeel Natu wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); 1048f02c5e4SNeel Natu wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); 1058f02c5e4SNeel Natu wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); 1068f02c5e4SNeel Natu 1078f02c5e4SNeel Natu /* MSR_KGSBASE will be restored on the way back to userspace */ 1088f02c5e4SNeel Natu } 1098f02c5e4SNeel Natu 1108f02c5e4SNeel Natu int 111*80cb5d84SJohn Baldwin svm_rdmsr(struct svm_vcpu *vcpu, u_int num, uint64_t *result, bool *retu) 1128f02c5e4SNeel Natu { 1138f02c5e4SNeel Natu int error = 0; 1148f02c5e4SNeel Natu 1158f02c5e4SNeel Natu switch (num) { 1161d29bfc1SNeel Natu case MSR_MCG_CAP: 1171d29bfc1SNeel Natu case MSR_MCG_STATUS: 1181d29bfc1SNeel Natu *result = 0; 1191d29bfc1SNeel Natu break; 1207d786ee2SNeel Natu case MSR_MTRRcap: 1217d786ee2SNeel Natu case MSR_MTRRdefType: 1226171e026SCorvin Köhne case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7: 1237d786ee2SNeel Natu case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: 1247d786ee2SNeel Natu case MSR_MTRR64kBase: 1256171e026SCorvin Köhne case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: 1261aa51504SJohn Baldwin if (vm_rdmtrr(&vcpu->mtrr, num, result) != 0) { 127d3956e46SJohn Baldwin vm_inject_gp(vcpu->vcpu); 1286171e026SCorvin Köhne } 1296171e026SCorvin Köhne break; 130fe22991fSNeel Natu case MSR_SYSCFG: 1318f02c5e4SNeel Natu case MSR_AMDK8_IPM: 1325bae7542SMarcelo Araujo case MSR_EXTFEATURES: 1335bae7542SMarcelo Araujo *result = 0; 1345bae7542SMarcelo Araujo break; 1358f02c5e4SNeel Natu default: 1368f02c5e4SNeel Natu error = EINVAL; 1378f02c5e4SNeel Natu break; 1388f02c5e4SNeel Natu } 1398f02c5e4SNeel Natu 1408f02c5e4SNeel Natu return (error); 1418f02c5e4SNeel Natu } 1428f02c5e4SNeel Natu 1438f02c5e4SNeel Natu int 144*80cb5d84SJohn Baldwin svm_wrmsr(struct svm_vcpu *vcpu, u_int num, uint64_t val, bool *retu) 1458f02c5e4SNeel Natu { 1468f02c5e4SNeel Natu int error = 0; 1478f02c5e4SNeel Natu 1488f02c5e4SNeel Natu switch (num) { 1491d29bfc1SNeel Natu case MSR_MCG_CAP: 1501d29bfc1SNeel Natu case MSR_MCG_STATUS: 1511d29bfc1SNeel Natu break; /* ignore writes */ 1527d786ee2SNeel Natu case MSR_MTRRcap: 1537d786ee2SNeel Natu case MSR_MTRRdefType: 1546171e026SCorvin Köhne case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7: 1557d786ee2SNeel Natu case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: 1567d786ee2SNeel Natu case MSR_MTRR64kBase: 1576171e026SCorvin Köhne case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: 1581aa51504SJohn Baldwin if (vm_wrmtrr(&vcpu->mtrr, num, val) != 0) { 159d3956e46SJohn Baldwin vm_inject_gp(vcpu->vcpu); 1606171e026SCorvin Köhne } 1616171e026SCorvin Köhne break; 162fe22991fSNeel Natu case MSR_SYSCFG: 1637d786ee2SNeel Natu break; /* Ignore writes */ 1648f02c5e4SNeel Natu case MSR_AMDK8_IPM: 1658f02c5e4SNeel Natu /* 1668f02c5e4SNeel Natu * Ignore writes to the "Interrupt Pending Message" MSR. 1678f02c5e4SNeel Natu */ 1688f02c5e4SNeel Natu break; 169441a3497SAnish Gupta case MSR_K8_UCODE_UPDATE: 170441a3497SAnish Gupta /* 171441a3497SAnish Gupta * Ignore writes to microcode update register. 172441a3497SAnish Gupta */ 173441a3497SAnish Gupta break; 174483d953aSJohn Baldwin #ifdef BHYVE_SNAPSHOT 175483d953aSJohn Baldwin case MSR_TSC: 176*80cb5d84SJohn Baldwin svm_set_tsc_offset(vcpu, val - rdtsc()); 177483d953aSJohn Baldwin break; 178483d953aSJohn Baldwin #endif 1795bae7542SMarcelo Araujo case MSR_EXTFEATURES: 1805bae7542SMarcelo Araujo break; 1818f02c5e4SNeel Natu default: 1828f02c5e4SNeel Natu error = EINVAL; 1838f02c5e4SNeel Natu break; 1848f02c5e4SNeel Natu } 1858f02c5e4SNeel Natu 1868f02c5e4SNeel Natu return (error); 1878f02c5e4SNeel Natu } 188