1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 NetApp, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <assert.h> 30 #include <err.h> 31 #include <stdbool.h> 32 #include <stdlib.h> 33 34 #include <vmmapi.h> 35 36 #include "acpi.h" 37 #include "atkbdc.h" 38 #include "bhyverun.h" 39 #include "config.h" 40 #include "debug.h" 41 #include "e820.h" 42 #include "fwctl.h" 43 #include "ioapic.h" 44 #include "inout.h" 45 #include "kernemu_dev.h" 46 #include "mptbl.h" 47 #include "pci_irq.h" 48 #include "pci_lpc.h" 49 #include "rtc.h" 50 #include "smbiostbl.h" 51 #include "xmsr.h" 52 53 void 54 bhyve_init_config(void) 55 { 56 init_config(); 57 58 /* Set default values prior to option parsing. */ 59 set_config_bool("acpi_tables", true); 60 set_config_bool("acpi_tables_in_memory", true); 61 set_config_value("memory.size", "256M"); 62 set_config_bool("x86.strictmsr", true); 63 set_config_value("lpc.fwcfg", "bhyve"); 64 } 65 66 void 67 bhyve_init_vcpu(struct vcpu *vcpu) 68 { 69 int err, tmp; 70 71 if (get_config_bool_default("x86.vmexit_on_hlt", false)) { 72 err = vm_get_capability(vcpu, VM_CAP_HALT_EXIT, &tmp); 73 if (err < 0) { 74 EPRINTLN("VM exit on HLT not supported"); 75 exit(4); 76 } 77 vm_set_capability(vcpu, VM_CAP_HALT_EXIT, 1); 78 } 79 80 if (get_config_bool_default("x86.vmexit_on_pause", false)) { 81 /* 82 * pause exit support required for this mode 83 */ 84 err = vm_get_capability(vcpu, VM_CAP_PAUSE_EXIT, &tmp); 85 if (err < 0) { 86 EPRINTLN("SMP mux requested, no pause support"); 87 exit(4); 88 } 89 vm_set_capability(vcpu, VM_CAP_PAUSE_EXIT, 1); 90 } 91 92 if (get_config_bool_default("x86.x2apic", false)) 93 err = vm_set_x2apic_state(vcpu, X2APIC_ENABLED); 94 else 95 err = vm_set_x2apic_state(vcpu, X2APIC_DISABLED); 96 97 if (err) { 98 EPRINTLN("Unable to set x2apic state (%d)", err); 99 exit(4); 100 } 101 102 vm_set_capability(vcpu, VM_CAP_ENABLE_INVPCID, 1); 103 104 err = vm_set_capability(vcpu, VM_CAP_IPI_EXIT, 1); 105 assert(err == 0); 106 } 107 108 void 109 bhyve_start_vcpu(struct vcpu *vcpu, bool bsp) 110 { 111 int error; 112 113 if (bsp) { 114 if (lpc_bootrom()) { 115 error = vm_set_capability(vcpu, 116 VM_CAP_UNRESTRICTED_GUEST, 1); 117 if (error != 0) { 118 err(4, "ROM boot failed: unrestricted guest " 119 "capability not available"); 120 } 121 error = vcpu_reset(vcpu); 122 assert(error == 0); 123 } 124 } else { 125 bhyve_init_vcpu(vcpu); 126 127 /* 128 * Enable the 'unrestricted guest' mode for APs. 129 * 130 * APs startup in power-on 16-bit mode. 131 */ 132 error = vm_set_capability(vcpu, VM_CAP_UNRESTRICTED_GUEST, 1); 133 assert(error == 0); 134 } 135 136 fbsdrun_addcpu(vcpu_id(vcpu)); 137 } 138 139 int 140 bhyve_init_platform(struct vmctx *ctx, struct vcpu *bsp __unused) 141 { 142 int error; 143 144 error = init_msr(); 145 if (error != 0) 146 return (error); 147 init_inout(); 148 kernemu_dev_init(); 149 atkbdc_init(ctx); 150 pci_irq_init(ctx); 151 ioapic_init(ctx); 152 rtc_init(ctx); 153 sci_init(ctx); 154 error = e820_init(ctx); 155 if (error != 0) 156 return (error); 157 158 return (0); 159 } 160 161 int 162 bhyve_init_platform_late(struct vmctx *ctx, struct vcpu *bsp __unused) 163 { 164 int error; 165 166 if (get_config_bool_default("x86.mptable", true)) { 167 error = mptable_build(ctx, guest_ncpus); 168 if (error != 0) 169 return (error); 170 } 171 error = smbios_build(ctx); 172 if (error != 0) 173 return (error); 174 error = e820_finalize(); 175 if (error != 0) 176 return (error); 177 178 if (lpc_bootrom() && strcmp(lpc_fwcfg(), "bhyve") == 0) 179 fwctl_init(); 180 181 if (get_config_bool("acpi_tables")) { 182 error = acpi_build(ctx, guest_ncpus); 183 assert(error == 0); 184 } 185 186 return (0); 187 } 188