17c8c0b82SPatrick Mooney /*- 27c8c0b82SPatrick Mooney * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 37c8c0b82SPatrick Mooney * 47c8c0b82SPatrick Mooney * Copyright (c) 2014, Neel Natu (neel@freebsd.org) 57c8c0b82SPatrick Mooney * All rights reserved. 67c8c0b82SPatrick Mooney * 77c8c0b82SPatrick Mooney * Redistribution and use in source and binary forms, with or without 87c8c0b82SPatrick Mooney * modification, are permitted provided that the following conditions 97c8c0b82SPatrick Mooney * are met: 107c8c0b82SPatrick Mooney * 1. Redistributions of source code must retain the above copyright 117c8c0b82SPatrick Mooney * notice unmodified, this list of conditions, and the following 127c8c0b82SPatrick Mooney * disclaimer. 137c8c0b82SPatrick Mooney * 2. Redistributions in binary form must reproduce the above copyright 147c8c0b82SPatrick Mooney * notice, this list of conditions and the following disclaimer in the 157c8c0b82SPatrick Mooney * documentation and/or other materials provided with the distribution. 167c8c0b82SPatrick Mooney * 177c8c0b82SPatrick Mooney * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 187c8c0b82SPatrick Mooney * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 197c8c0b82SPatrick Mooney * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 207c8c0b82SPatrick Mooney * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 217c8c0b82SPatrick Mooney * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 227c8c0b82SPatrick Mooney * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237c8c0b82SPatrick Mooney * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247c8c0b82SPatrick Mooney * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257c8c0b82SPatrick Mooney * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 267c8c0b82SPatrick Mooney * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277c8c0b82SPatrick Mooney */ 287c8c0b82SPatrick Mooney /* 297c8c0b82SPatrick Mooney * This file and its contents are supplied under the terms of the 307c8c0b82SPatrick Mooney * Common Development and Distribution License ("CDDL"), version 1.0. 317c8c0b82SPatrick Mooney * You may only use this file in accordance with the terms of version 327c8c0b82SPatrick Mooney * 1.0 of the CDDL. 337c8c0b82SPatrick Mooney * 347c8c0b82SPatrick Mooney * A full copy of the text of the CDDL should have accompanied this 357c8c0b82SPatrick Mooney * source. A copy of the CDDL is also available via the Internet at 367c8c0b82SPatrick Mooney * http://www.illumos.org/license/CDDL. 377c8c0b82SPatrick Mooney * 387c8c0b82SPatrick Mooney * Copyright 2020 Oxide Computer Company 397c8c0b82SPatrick Mooney */ 407c8c0b82SPatrick Mooney 417c8c0b82SPatrick Mooney #include <sys/cdefs.h> 427c8c0b82SPatrick Mooney __FBSDID("$FreeBSD$"); 437c8c0b82SPatrick Mooney 447c8c0b82SPatrick Mooney #include <sys/param.h> 457c8c0b82SPatrick Mooney #include <sys/errno.h> 467c8c0b82SPatrick Mooney #include <sys/systm.h> 477c8c0b82SPatrick Mooney #include <sys/x86_archext.h> 487c8c0b82SPatrick Mooney #include <sys/privregs.h> 497c8c0b82SPatrick Mooney 507c8c0b82SPatrick Mooney #include <machine/cpufunc.h> 517c8c0b82SPatrick Mooney #include <machine/specialreg.h> 527c8c0b82SPatrick Mooney #include <machine/vmm.h> 537c8c0b82SPatrick Mooney #include <sys/vmm_kernel.h> 547c8c0b82SPatrick Mooney 557c8c0b82SPatrick Mooney #include "svm.h" 567c8c0b82SPatrick Mooney #include "vmcb.h" 577c8c0b82SPatrick Mooney #include "svm_softc.h" 587c8c0b82SPatrick Mooney #include "svm_msr.h" 597c8c0b82SPatrick Mooney 607c8c0b82SPatrick Mooney #ifndef MSR_AMDK8_IPM 617c8c0b82SPatrick Mooney #define MSR_AMDK8_IPM 0xc0010055 627c8c0b82SPatrick Mooney #endif 637c8c0b82SPatrick Mooney 647c8c0b82SPatrick Mooney enum { 657c8c0b82SPatrick Mooney IDX_MSR_LSTAR, 667c8c0b82SPatrick Mooney IDX_MSR_CSTAR, 677c8c0b82SPatrick Mooney IDX_MSR_STAR, 687c8c0b82SPatrick Mooney IDX_MSR_SF_MASK, 697c8c0b82SPatrick Mooney HOST_MSR_NUM /* must be the last enumeration */ 707c8c0b82SPatrick Mooney }; 717c8c0b82SPatrick Mooney CTASSERT(HOST_MSR_NUM == SVM_HOST_MSR_NUM); 727c8c0b82SPatrick Mooney 737c8c0b82SPatrick Mooney void 747c8c0b82SPatrick Mooney svm_msr_init(void) 757c8c0b82SPatrick Mooney { 767c8c0b82SPatrick Mooney /* 777c8c0b82SPatrick Mooney * These MSRs do vary between CPUs on illumos, so saving system-wide 787c8c0b82SPatrick Mooney * values for them serves no purpose. 797c8c0b82SPatrick Mooney */ 807c8c0b82SPatrick Mooney } 817c8c0b82SPatrick Mooney 827c8c0b82SPatrick Mooney void 837c8c0b82SPatrick Mooney svm_msr_guest_init(struct svm_softc *sc, int vcpu) 847c8c0b82SPatrick Mooney { 857c8c0b82SPatrick Mooney /* 867c8c0b82SPatrick Mooney * All the MSRs accessible to the guest are either saved/restored by 877c8c0b82SPatrick Mooney * hardware on every #VMEXIT/VMRUN (e.g., G_PAT) or are saved/restored 887c8c0b82SPatrick Mooney * by VMSAVE/VMLOAD (e.g., MSR_GSBASE). 897c8c0b82SPatrick Mooney * 907c8c0b82SPatrick Mooney * There are no guest MSRs that are saved/restored "by hand" so nothing 917c8c0b82SPatrick Mooney * more to do here. 927c8c0b82SPatrick Mooney */ 937c8c0b82SPatrick Mooney } 947c8c0b82SPatrick Mooney 957c8c0b82SPatrick Mooney void 967c8c0b82SPatrick Mooney svm_msr_guest_enter(struct svm_softc *sc, int vcpu) 977c8c0b82SPatrick Mooney { 987c8c0b82SPatrick Mooney uint64_t *host_msrs = sc->host_msrs[vcpu]; 997c8c0b82SPatrick Mooney 1007c8c0b82SPatrick Mooney /* 1017c8c0b82SPatrick Mooney * Save host MSRs (if any) and restore guest MSRs (if any). 1027c8c0b82SPatrick Mooney */ 1037c8c0b82SPatrick Mooney host_msrs[IDX_MSR_LSTAR] = rdmsr(MSR_LSTAR); 1047c8c0b82SPatrick Mooney host_msrs[IDX_MSR_CSTAR] = rdmsr(MSR_CSTAR); 1057c8c0b82SPatrick Mooney host_msrs[IDX_MSR_STAR] = rdmsr(MSR_STAR); 1067c8c0b82SPatrick Mooney host_msrs[IDX_MSR_SF_MASK] = rdmsr(MSR_SF_MASK); 107*717646f7SJordan Paige Hendricks 108*717646f7SJordan Paige Hendricks /* 109*717646f7SJordan Paige Hendricks * Set the frequency multiplier MSR to enable guest TSC scaling if 110*717646f7SJordan Paige Hendricks * needed. 111*717646f7SJordan Paige Hendricks */ 112*717646f7SJordan Paige Hendricks uint64_t mult = vm_get_freq_multiplier(sc->vm); 113*717646f7SJordan Paige Hendricks if (mult != VM_TSCM_NOSCALE) { 114*717646f7SJordan Paige Hendricks wrmsr(MSR_AMD_TSC_RATIO, mult); 115*717646f7SJordan Paige Hendricks } 1167c8c0b82SPatrick Mooney } 1177c8c0b82SPatrick Mooney 1187c8c0b82SPatrick Mooney void 1197c8c0b82SPatrick Mooney svm_msr_guest_exit(struct svm_softc *sc, int vcpu) 1207c8c0b82SPatrick Mooney { 1217c8c0b82SPatrick Mooney uint64_t *host_msrs = sc->host_msrs[vcpu]; 1227c8c0b82SPatrick Mooney 1237c8c0b82SPatrick Mooney /* 1247c8c0b82SPatrick Mooney * Save guest MSRs (if any) and restore host MSRs. 1257c8c0b82SPatrick Mooney */ 1267c8c0b82SPatrick Mooney wrmsr(MSR_LSTAR, host_msrs[IDX_MSR_LSTAR]); 1277c8c0b82SPatrick Mooney wrmsr(MSR_CSTAR, host_msrs[IDX_MSR_CSTAR]); 1287c8c0b82SPatrick Mooney wrmsr(MSR_STAR, host_msrs[IDX_MSR_STAR]); 1297c8c0b82SPatrick Mooney wrmsr(MSR_SF_MASK, host_msrs[IDX_MSR_SF_MASK]); 1307c8c0b82SPatrick Mooney 131*717646f7SJordan Paige Hendricks /* Reset frequency multiplier MSR */ 132*717646f7SJordan Paige Hendricks wrmsr(MSR_AMD_TSC_RATIO, AMD_TSCM_RESET_VAL); 133*717646f7SJordan Paige Hendricks 1347c8c0b82SPatrick Mooney /* MSR_KGSBASE will be restored on the way back to userspace */ 1357c8c0b82SPatrick Mooney } 1367c8c0b82SPatrick Mooney 1377c8c0b82SPatrick Mooney vm_msr_result_t 1387c8c0b82SPatrick Mooney svm_rdmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t *result) 1397c8c0b82SPatrick Mooney { 1407c8c0b82SPatrick Mooney switch (num) { 1417c8c0b82SPatrick Mooney case MSR_SYSCFG: 1427c8c0b82SPatrick Mooney case MSR_AMDK8_IPM: 1437c8c0b82SPatrick Mooney case MSR_EXTFEATURES: 1447c8c0b82SPatrick Mooney *result = 0; 1457c8c0b82SPatrick Mooney break; 1467c8c0b82SPatrick Mooney case MSR_AMD_DE_CFG: 1477c8c0b82SPatrick Mooney *result = 0; 1487c8c0b82SPatrick Mooney /* 1497c8c0b82SPatrick Mooney * Bit 1 of DE_CFG is defined by AMD to control whether the 1507c8c0b82SPatrick Mooney * lfence instruction is serializing. Practically all CPUs 1517c8c0b82SPatrick Mooney * supported by bhyve also contain this MSR, making it safe to 1527c8c0b82SPatrick Mooney * expose unconditionally. 1537c8c0b82SPatrick Mooney */ 1547c8c0b82SPatrick Mooney if (is_x86_feature(x86_featureset, X86FSET_LFENCE_SER)) { 1557c8c0b82SPatrick Mooney *result |= AMD_DE_CFG_LFENCE_DISPATCH; 1567c8c0b82SPatrick Mooney } 1577c8c0b82SPatrick Mooney break; 1587c8c0b82SPatrick Mooney default: 1597c8c0b82SPatrick Mooney return (VMR_UNHANLDED); 1607c8c0b82SPatrick Mooney } 1617c8c0b82SPatrick Mooney return (VMR_OK); 1627c8c0b82SPatrick Mooney } 1637c8c0b82SPatrick Mooney 1647c8c0b82SPatrick Mooney vm_msr_result_t 1657c8c0b82SPatrick Mooney svm_wrmsr(struct svm_softc *sc, int vcpu, uint32_t num, uint64_t val) 1667c8c0b82SPatrick Mooney { 1677c8c0b82SPatrick Mooney switch (num) { 1687c8c0b82SPatrick Mooney case MSR_SYSCFG: 1697c8c0b82SPatrick Mooney /* Ignore writes */ 1707c8c0b82SPatrick Mooney break; 1717c8c0b82SPatrick Mooney case MSR_AMD_DE_CFG: 1727c8c0b82SPatrick Mooney /* Ignore writes */ 1737c8c0b82SPatrick Mooney break; 1747c8c0b82SPatrick Mooney case MSR_AMDK8_IPM: 1757c8c0b82SPatrick Mooney /* 1767c8c0b82SPatrick Mooney * Ignore writes to the "Interrupt Pending Message" MSR. 1777c8c0b82SPatrick Mooney */ 1787c8c0b82SPatrick Mooney break; 1797c8c0b82SPatrick Mooney case MSR_K8_UCODE_UPDATE: 1807c8c0b82SPatrick Mooney /* 1817c8c0b82SPatrick Mooney * Ignore writes to microcode update register. 1827c8c0b82SPatrick Mooney */ 1837c8c0b82SPatrick Mooney break; 1847c8c0b82SPatrick Mooney case MSR_EXTFEATURES: 1857c8c0b82SPatrick Mooney break; 1867c8c0b82SPatrick Mooney default: 1877c8c0b82SPatrick Mooney return (VMR_UNHANLDED); 1887c8c0b82SPatrick Mooney } 1897c8c0b82SPatrick Mooney 1907c8c0b82SPatrick Mooney return (VMR_OK); 1917c8c0b82SPatrick Mooney } 192