1*7c8c0b82SPatrick Mooney /*- 2*7c8c0b82SPatrick Mooney * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*7c8c0b82SPatrick Mooney * 4*7c8c0b82SPatrick Mooney * Copyright (c) 2014, Neel Natu (neel@freebsd.org) 5*7c8c0b82SPatrick Mooney * All rights reserved. 6*7c8c0b82SPatrick Mooney * 7*7c8c0b82SPatrick Mooney * Redistribution and use in source and binary forms, with or without 8*7c8c0b82SPatrick Mooney * modification, are permitted provided that the following conditions 9*7c8c0b82SPatrick Mooney * are met: 10*7c8c0b82SPatrick Mooney * 1. Redistributions of source code must retain the above copyright 11*7c8c0b82SPatrick Mooney * notice unmodified, this list of conditions, and the following 12*7c8c0b82SPatrick Mooney * disclaimer. 13*7c8c0b82SPatrick Mooney * 2. Redistributions in binary form must reproduce the above copyright 14*7c8c0b82SPatrick Mooney * notice, this list of conditions and the following disclaimer in the 15*7c8c0b82SPatrick Mooney * documentation and/or other materials provided with the distribution. 16*7c8c0b82SPatrick Mooney * 17*7c8c0b82SPatrick Mooney * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18*7c8c0b82SPatrick Mooney * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19*7c8c0b82SPatrick Mooney * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20*7c8c0b82SPatrick Mooney * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21*7c8c0b82SPatrick Mooney * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22*7c8c0b82SPatrick Mooney * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23*7c8c0b82SPatrick Mooney * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24*7c8c0b82SPatrick Mooney * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25*7c8c0b82SPatrick Mooney * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26*7c8c0b82SPatrick Mooney * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*7c8c0b82SPatrick Mooney */ 28*7c8c0b82SPatrick Mooney /* 29*7c8c0b82SPatrick Mooney * This file and its contents are supplied under the terms of the 30*7c8c0b82SPatrick Mooney * Common Development and Distribution License ("CDDL"), version 1.0. 31*7c8c0b82SPatrick Mooney * You may only use this file in accordance with the terms of version 32*7c8c0b82SPatrick Mooney * 1.0 of the CDDL. 33*7c8c0b82SPatrick Mooney * 34*7c8c0b82SPatrick Mooney * A full copy of the text of the CDDL should have accompanied this 35*7c8c0b82SPatrick Mooney * source. A copy of the CDDL is also available via the Internet at 36*7c8c0b82SPatrick Mooney * http://www.illumos.org/license/CDDL. 37*7c8c0b82SPatrick Mooney * 38*7c8c0b82SPatrick Mooney * Copyright 2020 Oxide Computer Company 39*7c8c0b82SPatrick Mooney */ 40*7c8c0b82SPatrick Mooney 41*7c8c0b82SPatrick Mooney #include <sys/cdefs.h> 42*7c8c0b82SPatrick Mooney __FBSDID("$FreeBSD$"); 43*7c8c0b82SPatrick Mooney 44*7c8c0b82SPatrick Mooney #include <sys/param.h> 45*7c8c0b82SPatrick Mooney #include <sys/errno.h> 46*7c8c0b82SPatrick Mooney #include <sys/systm.h> 47*7c8c0b82SPatrick Mooney #include <sys/x86_archext.h> 48*7c8c0b82SPatrick Mooney #include <sys/privregs.h> 49*7c8c0b82SPatrick Mooney 50*7c8c0b82SPatrick Mooney #include <machine/cpufunc.h> 51*7c8c0b82SPatrick Mooney #include <machine/specialreg.h> 52*7c8c0b82SPatrick Mooney #include <machine/vmm.h> 53*7c8c0b82SPatrick Mooney #include <sys/vmm_kernel.h> 54*7c8c0b82SPatrick Mooney 55*7c8c0b82SPatrick Mooney #include "svm.h" 56*7c8c0b82SPatrick Mooney #include "vmcb.h" 57*7c8c0b82SPatrick Mooney #include "svm_softc.h" 58*7c8c0b82SPatrick Mooney #include "svm_msr.h" 59*7c8c0b82SPatrick Mooney 60*7c8c0b82SPatrick Mooney #ifndef MSR_AMDK8_IPM 61*7c8c0b82SPatrick Mooney #define MSR_AMDK8_IPM 0xc0010055 62*7c8c0b82SPatrick Mooney #endif 63*7c8c0b82SPatrick Mooney 64*7c8c0b82SPatrick Mooney enum { 65*7c8c0b82SPatrick Mooney IDX_MSR_LSTAR, 66*7c8c0b82SPatrick Mooney IDX_MSR_CSTAR, 67*7c8c0b82SPatrick Mooney IDX_MSR_STAR, 68*7c8c0b82SPatrick Mooney IDX_MSR_SF_MASK, 69*7c8c0b82SPatrick Mooney HOST_MSR_NUM /* must be the last enumeration */ 70*7c8c0b82SPatrick Mooney }; 71*7c8c0b82SPatrick Mooney CTASSERT(HOST_MSR_NUM == SVM_HOST_MSR_NUM); 72*7c8c0b82SPatrick Mooney 73*7c8c0b82SPatrick Mooney void 74*7c8c0b82SPatrick Mooney svm_msr_init(void) 75*7c8c0b82SPatrick Mooney { 76*7c8c0b82SPatrick Mooney /* 77*7c8c0b82SPatrick Mooney * These MSRs do vary between CPUs on illumos, so saving system-wide 78*7c8c0b82SPatrick Mooney * values for them serves no purpose. 79*7c8c0b82SPatrick Mooney */ 80*7c8c0b82SPatrick Mooney } 81*7c8c0b82SPatrick Mooney 82*7c8c0b82SPatrick Mooney void 83*7c8c0b82SPatrick Mooney svm_msr_guest_init(struct svm_softc *sc, int vcpu) 84*7c8c0b82SPatrick Mooney { 85*7c8c0b82SPatrick Mooney /* 86*7c8c0b82SPatrick Mooney * All the MSRs accessible to the guest are either saved/restored by 87*7c8c0b82SPatrick Mooney * hardware on every #VMEXIT/VMRUN (e.g., G_PAT) or are saved/restored 88*7c8c0b82SPatrick Mooney * by VMSAVE/VMLOAD (e.g., MSR_GSBASE). 89*7c8c0b82SPatrick Mooney * 90*7c8c0b82SPatrick Mooney * There are no guest MSRs that are saved/restored "by hand" so nothing 91*7c8c0b82SPatrick Mooney * more to do here. 92*7c8c0b82SPatrick Mooney */ 93*7c8c0b82SPatrick Mooney } 94*7c8c0b82SPatrick Mooney 95*7c8c0b82SPatrick Mooney void 96*7c8c0b82SPatrick Mooney svm_msr_guest_enter(struct svm_softc *sc, int vcpu) 97*7c8c0b82SPatrick Mooney { 98*7c8c0b82SPatrick Mooney uint64_t *host_msrs = sc->host_msrs[vcpu]; 99*7c8c0b82SPatrick Mooney 100*7c8c0b82SPatrick Mooney /* 101*7c8c0b82SPatrick Mooney * Save host MSRs (if any) and restore guest MSRs (if any). 102*7c8c0b82SPatrick Mooney */ 103*7c8c0b82SPatrick Mooney host_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); 104*7c8c0b82SPatrick Mooney host_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); 105*7c8c0b82SPatrick Mooney host_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); 106*7c8c0b82SPatrick Mooney host_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); 107*7c8c0b82SPatrick Mooney } 108*7c8c0b82SPatrick Mooney 109*7c8c0b82SPatrick Mooney void 110*7c8c0b82SPatrick Mooney svm_msr_guest_exit(struct svm_softc *sc, int vcpu) 111*7c8c0b82SPatrick Mooney { 112*7c8c0b82SPatrick Mooney uint64_t *host_msrs = sc->host_msrs[vcpu]; 113*7c8c0b82SPatrick Mooney 114*7c8c0b82SPatrick Mooney /* 115*7c8c0b82SPatrick Mooney * Save guest MSRs (if any) and restore host MSRs. 116*7c8c0b82SPatrick Mooney */ 117*7c8c0b82SPatrick Mooney wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); 118*7c8c0b82SPatrick Mooney wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); 119*7c8c0b82SPatrick Mooney wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); 120*7c8c0b82SPatrick Mooney wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); 121*7c8c0b82SPatrick Mooney 122*7c8c0b82SPatrick Mooney /* MSR_KGSBASE will be restored on the way back to userspace */ 123*7c8c0b82SPatrick Mooney } 124*7c8c0b82SPatrick Mooney 125*7c8c0b82SPatrick Mooney vm_msr_result_t 126*7c8c0b82SPatrick Mooney svm_rdmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t *result) 127*7c8c0b82SPatrick Mooney { 128*7c8c0b82SPatrick Mooney switch (num) { 129*7c8c0b82SPatrick Mooney case MSR_SYSCFG: 130*7c8c0b82SPatrick Mooney case MSR_AMDK8_IPM: 131*7c8c0b82SPatrick Mooney case MSR_EXTFEATURES: 132*7c8c0b82SPatrick Mooney *result = 0; 133*7c8c0b82SPatrick Mooney break; 134*7c8c0b82SPatrick Mooney case MSR_AMD_DE_CFG: 135*7c8c0b82SPatrick Mooney *result = 0; 136*7c8c0b82SPatrick Mooney /* 137*7c8c0b82SPatrick Mooney * Bit 1 of DE_CFG is defined by AMD to control whether the 138*7c8c0b82SPatrick Mooney * lfence instruction is serializing. Practically all CPUs 139*7c8c0b82SPatrick Mooney * supported by bhyve also contain this MSR, making it safe to 140*7c8c0b82SPatrick Mooney * expose unconditionally. 141*7c8c0b82SPatrick Mooney */ 142*7c8c0b82SPatrick Mooney if (is_x86_feature(x86_featureset, X86FSET_LFENCE_SER)) { 143*7c8c0b82SPatrick Mooney *result |= AMD_DE_CFG_LFENCE_DISPATCH; 144*7c8c0b82SPatrick Mooney } 145*7c8c0b82SPatrick Mooney break; 146*7c8c0b82SPatrick Mooney default: 147*7c8c0b82SPatrick Mooney return (VMR_UNHANLDED); 148*7c8c0b82SPatrick Mooney } 149*7c8c0b82SPatrick Mooney return (VMR_OK); 150*7c8c0b82SPatrick Mooney } 151*7c8c0b82SPatrick Mooney 152*7c8c0b82SPatrick Mooney vm_msr_result_t 153*7c8c0b82SPatrick Mooney svm_wrmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t val) 154*7c8c0b82SPatrick Mooney { 155*7c8c0b82SPatrick Mooney switch (num) { 156*7c8c0b82SPatrick Mooney case MSR_SYSCFG: 157*7c8c0b82SPatrick Mooney /* Ignore writes */ 158*7c8c0b82SPatrick Mooney break; 159*7c8c0b82SPatrick Mooney case MSR_AMD_DE_CFG: 160*7c8c0b82SPatrick Mooney /* Ignore writes */ 161*7c8c0b82SPatrick Mooney break; 162*7c8c0b82SPatrick Mooney case MSR_AMDK8_IPM: 163*7c8c0b82SPatrick Mooney /* 164*7c8c0b82SPatrick Mooney * Ignore writes to the "Interrupt Pending Message" MSR. 165*7c8c0b82SPatrick Mooney */ 166*7c8c0b82SPatrick Mooney break; 167*7c8c0b82SPatrick Mooney case MSR_K8_UCODE_UPDATE: 168*7c8c0b82SPatrick Mooney /* 169*7c8c0b82SPatrick Mooney * Ignore writes to microcode update register. 170*7c8c0b82SPatrick Mooney */ 171*7c8c0b82SPatrick Mooney break; 172*7c8c0b82SPatrick Mooney case MSR_EXTFEATURES: 173*7c8c0b82SPatrick Mooney break; 174*7c8c0b82SPatrick Mooney default: 175*7c8c0b82SPatrick Mooney return (VMR_UNHANLDED); 176*7c8c0b82SPatrick Mooney } 177*7c8c0b82SPatrick Mooney 178*7c8c0b82SPatrick Mooney return (VMR_OK); 179*7c8c0b82SPatrick Mooney } 180