1271912Sneel/*- 2336190Saraujo * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3336190Saraujo * 4271912Sneel * Copyright (c) 2014, Neel Natu (neel@freebsd.org) 5271912Sneel * All rights reserved. 6271912Sneel * 7271912Sneel * Redistribution and use in source and binary forms, with or without 8271912Sneel * modification, are permitted provided that the following conditions 9271912Sneel * are met: 10271912Sneel * 1. Redistributions of source code must retain the above copyright 11271912Sneel * notice unmodified, this list of conditions, and the following 12271912Sneel * disclaimer. 13271912Sneel * 2. Redistributions in binary form must reproduce the above copyright 14271912Sneel * notice, this list of conditions and the following disclaimer in the 15271912Sneel * documentation and/or other materials provided with the distribution. 16271912Sneel * 17271912Sneel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18271912Sneel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19271912Sneel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20271912Sneel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21271912Sneel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22271912Sneel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23271912Sneel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24271912Sneel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25271912Sneel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26271912Sneel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27271912Sneel */ 28271912Sneel 29271912Sneel#include <sys/cdefs.h> 30271912Sneel__FBSDID("$FreeBSD: stable/11/sys/amd64/vmm/amd/svm_msr.c 349958 2019-07-12 22:31:12Z jhb $"); 31271912Sneel 32282281Sneel#include <sys/param.h> 33271912Sneel#include <sys/errno.h> 34282281Sneel#include <sys/systm.h> 35271912Sneel 36271912Sneel#include <machine/cpufunc.h> 37271912Sneel#include <machine/specialreg.h> 38282281Sneel#include <machine/vmm.h> 39271912Sneel 40282281Sneel#include "svm.h" 41282281Sneel#include "vmcb.h" 42282281Sneel#include "svm_softc.h" 43271912Sneel#include "svm_msr.h" 44271912Sneel 45271912Sneel#ifndef MSR_AMDK8_IPM 46271912Sneel#define MSR_AMDK8_IPM 0xc0010055 47271912Sneel#endif 48271912Sneel 49271912Sneelenum { 50271912Sneel IDX_MSR_LSTAR, 51271912Sneel IDX_MSR_CSTAR, 52271912Sneel IDX_MSR_STAR, 53271912Sneel IDX_MSR_SF_MASK, 54271912Sneel HOST_MSR_NUM /* must be the last enumeration */ 55271912Sneel}; 56271912Sneel 57271912Sneelstatic uint64_t host_msrs[HOST_MSR_NUM]; 58271912Sneel 59271912Sneelvoid 60271912Sneelsvm_msr_init(void) 61271912Sneel{ 62271912Sneel /* 63271912Sneel * It is safe to cache the values of the following MSRs because they 64271912Sneel * don't change based on curcpu, curproc or curthread. 65271912Sneel */ 66271912Sneel host_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); 67271912Sneel host_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); 68271912Sneel host_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); 69271912Sneel host_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); 70271912Sneel} 71271912Sneel 72271912Sneelvoid 73271912Sneelsvm_msr_guest_init(struct svm_softc *sc, int vcpu) 74271912Sneel{ 75271912Sneel /* 76271912Sneel * All the MSRs accessible to the guest are either saved/restored by 77271912Sneel * hardware on every #VMEXIT/VMRUN (e.g., G_PAT) or are saved/restored 78271912Sneel * by VMSAVE/VMLOAD (e.g., MSR_GSBASE). 79271912Sneel * 80271912Sneel * There are no guest MSRs that are saved/restored "by hand" so nothing 81271912Sneel * more to do here. 82271912Sneel */ 83271912Sneel return; 84271912Sneel} 85271912Sneel 86271912Sneelvoid 87271912Sneelsvm_msr_guest_enter(struct svm_softc *sc, int vcpu) 88271912Sneel{ 89271912Sneel /* 90271912Sneel * Save host MSRs (if any) and restore guest MSRs (if any). 91271912Sneel */ 92271912Sneel} 93271912Sneel 94271912Sneelvoid 95271912Sneelsvm_msr_guest_exit(struct svm_softc *sc, int vcpu) 96271912Sneel{ 97271912Sneel /* 98271912Sneel * Save guest MSRs (if any) and restore host MSRs. 99271912Sneel */ 100271912Sneel wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); 101271912Sneel wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); 102271912Sneel wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); 103271912Sneel wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); 104271912Sneel 105271912Sneel /* MSR_KGSBASE will be restored on the way back to userspace */ 106271912Sneel} 107271912Sneel 108271912Sneelint 109271912Sneelsvm_rdmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t *result, 110271912Sneel bool *retu) 111271912Sneel{ 112271912Sneel int error = 0; 113271912Sneel 114271912Sneel switch (num) { 115282336Sneel case MSR_MCG_CAP: 116282336Sneel case MSR_MCG_STATUS: 117282336Sneel *result = 0; 118282336Sneel break; 119282281Sneel case MSR_MTRRcap: 120282281Sneel case MSR_MTRRdefType: 121282281Sneel case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8: 122282281Sneel case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: 123282281Sneel case MSR_MTRR64kBase: 124282296Sneel case MSR_SYSCFG: 125271912Sneel case MSR_AMDK8_IPM: 126349958Sjhb case MSR_EXTFEATURES: 127271912Sneel *result = 0; 128271912Sneel break; 129271912Sneel default: 130271912Sneel error = EINVAL; 131271912Sneel break; 132271912Sneel } 133271912Sneel 134271912Sneel return (error); 135271912Sneel} 136271912Sneel 137271912Sneelint 138271912Sneelsvm_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val, bool *retu) 139271912Sneel{ 140271912Sneel int error = 0; 141271912Sneel 142271912Sneel switch (num) { 143282336Sneel case MSR_MCG_CAP: 144282336Sneel case MSR_MCG_STATUS: 145282336Sneel break; /* ignore writes */ 146282281Sneel case MSR_MTRRcap: 147282281Sneel vm_inject_gp(sc->vm, vcpu); 148282281Sneel break; 149282281Sneel case MSR_MTRRdefType: 150282281Sneel case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8: 151282281Sneel case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1: 152282281Sneel case MSR_MTRR64kBase: 153282296Sneel case MSR_SYSCFG: 154282281Sneel break; /* Ignore writes */ 155271912Sneel case MSR_AMDK8_IPM: 156271912Sneel /* 157271912Sneel * Ignore writes to the "Interrupt Pending Message" MSR. 158271912Sneel */ 159271912Sneel break; 160297806Sanish case MSR_K8_UCODE_UPDATE: 161297806Sanish /* 162297806Sanish * Ignore writes to microcode update register. 163297806Sanish */ 164297806Sanish break; 165349958Sjhb case MSR_EXTFEATURES: 166349958Sjhb break; 167271912Sneel default: 168271912Sneel error = EINVAL; 169271912Sneel break; 170271912Sneel } 171271912Sneel 172271912Sneel return (error); 173271912Sneel} 174