diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -21,6 +21,7 @@ basl.c \ bhyvegc.c \ bhyverun.c \ + bhyverun_machdep.c \ block_if.c \ bootrom.c \ config.c \ diff --git a/usr.sbin/bhyve/amd64/bhyverun_machdep.c b/usr.sbin/bhyve/amd64/bhyverun_machdep.c new file mode 100644 --- /dev/null +++ b/usr.sbin/bhyve/amd64/bhyverun_machdep.c @@ -0,0 +1,125 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +#include "bhyverun.h" +#include "config.h" +#include "pci_lpc.h" + +void +bhyve_init_config(void) +{ + init_config(); + + /* Set default values prior to option parsing. */ + set_config_bool("acpi_tables", true); + set_config_bool("acpi_tables_in_memory", true); + set_config_value("memory.size", "256M"); + set_config_bool("x86.strictmsr", true); + set_config_value("lpc.fwcfg", "bhyve"); +} + +void +bhyve_init_vcpu(struct vcpu *vcpu) +{ + int err, tmp; + + if (get_config_bool_default("x86.vmexit_on_hlt", false)) { + err = vm_get_capability(vcpu, VM_CAP_HALT_EXIT, &tmp); + if (err < 0) { + fprintf(stderr, "VM exit on HLT not supported\n"); + exit(4); + } + vm_set_capability(vcpu, VM_CAP_HALT_EXIT, 1); + } + + if (get_config_bool_default("x86.vmexit_on_pause", false)) { + /* + * pause exit support required for this mode + */ + err = vm_get_capability(vcpu, VM_CAP_PAUSE_EXIT, &tmp); + if (err < 0) { + fprintf(stderr, + "SMP mux requested, no pause support\n"); + exit(4); + } + vm_set_capability(vcpu, VM_CAP_PAUSE_EXIT, 1); + } + + if (get_config_bool_default("x86.x2apic", false)) + err = vm_set_x2apic_state(vcpu, X2APIC_ENABLED); + else + err = vm_set_x2apic_state(vcpu, X2APIC_DISABLED); + + if (err) { + fprintf(stderr, "Unable to set x2apic state (%d)\n", err); + exit(4); + } + + vm_set_capability(vcpu, VM_CAP_ENABLE_INVPCID, 1); + + err = vm_set_capability(vcpu, VM_CAP_IPI_EXIT, 1); + assert(err == 0); +} + +void +bhyve_start_vcpu(struct vcpu *vcpu, bool bsp) +{ + int error; + + if (bsp) { + if (lpc_bootrom()) { + error = vm_set_capability(vcpu, + VM_CAP_UNRESTRICTED_GUEST, 1); + if (error != 0) { + err(4, "ROM boot failed: unrestricted guest " + "capability not available"); + } + error = vcpu_reset(vcpu); + assert(error == 0); + } + } else { + bhyve_init_vcpu(vcpu); + + /* + * Enable the 'unrestricted guest' mode for APs. + * + * APs startup in power-on 16-bit mode. + */ + error = vm_set_capability(vcpu, VM_CAP_UNRESTRICTED_GUEST, 1); + assert(error == 0); + } + + fbsdrun_addcpu(vcpu_id(vcpu)); +} diff --git a/usr.sbin/bhyve/bhyverun.h b/usr.sbin/bhyve/bhyverun.h --- a/usr.sbin/bhyve/bhyverun.h +++ b/usr.sbin/bhyve/bhyverun.h @@ -26,8 +26,10 @@ * SUCH DAMAGE. */ -#ifndef _FBSDRUN_H_ -#define _FBSDRUN_H_ +#ifndef _BHYVERUN_H_ +#define _BHYVERUN_H_ + +#include #define VMEXIT_CONTINUE (0) #define VMEXIT_ABORT (-1) @@ -46,6 +48,7 @@ struct vcpu; struct vcpu *fbsdrun_vcpu(int vcpuid); +void fbsdrun_addcpu(int vcpuid); void fbsdrun_deletecpu(int vcpuid); int fbsdrun_suspendcpu(int vcpuid); @@ -53,4 +56,9 @@ typedef int (*vmexit_handler_t)(struct vmctx *, struct vcpu *, struct vm_run *); +/* Interfaces implemented by machine-dependent code. */ +void bhyve_init_config(void); +void bhyve_init_vcpu(struct vcpu *vcpu); +void bhyve_start_vcpu(struct vcpu *vcpu, bool bsp); + #endif diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -476,17 +476,20 @@ return (NULL); } -static void -fbsdrun_addcpu(struct vcpu_info *vi) +void +fbsdrun_addcpu(int vcpuid) { + struct vcpu_info *vi; pthread_t thr; int error; + vi = &vcpu_info[vcpuid]; + error = vm_activate_cpu(vi->vcpu); if (error != 0) err(EX_OSERR, "could not activate CPU %d", vi->vcpuid); - CPU_SET_ATOMIC(vi->vcpuid, &cpumask); + CPU_SET_ATOMIC(vcpuid, &cpumask); vm_suspend_cpu(vi->vcpu); @@ -590,49 +593,6 @@ return (1); } -static void -fbsdrun_set_capabilities(struct vcpu *vcpu) -{ - int err, tmp; - - if (get_config_bool_default("x86.vmexit_on_hlt", false)) { - err = vm_get_capability(vcpu, VM_CAP_HALT_EXIT, &tmp); - if (err < 0) { - fprintf(stderr, "VM exit on HLT not supported\n"); - exit(4); - } - vm_set_capability(vcpu, VM_CAP_HALT_EXIT, 1); - } - - if (get_config_bool_default("x86.vmexit_on_pause", false)) { - /* - * pause exit support required for this mode - */ - err = vm_get_capability(vcpu, VM_CAP_PAUSE_EXIT, &tmp); - if (err < 0) { - fprintf(stderr, - "SMP mux requested, no pause support\n"); - exit(4); - } - vm_set_capability(vcpu, VM_CAP_PAUSE_EXIT, 1); - } - - if (get_config_bool_default("x86.x2apic", false)) - err = vm_set_x2apic_state(vcpu, X2APIC_ENABLED); - else - err = vm_set_x2apic_state(vcpu, X2APIC_DISABLED); - - if (err) { - fprintf(stderr, "Unable to set x2apic state (%d)\n", err); - exit(4); - } - - vm_set_capability(vcpu, VM_CAP_ENABLE_INVPCID, 1); - - err = vm_set_capability(vcpu, VM_CAP_IPI_EXIT, 1); - assert(err == 0); -} - static struct vmctx * do_open(const char *vmname) { @@ -697,26 +657,6 @@ return (ctx); } -static void -spinup_vcpu(struct vcpu_info *vi, bool bsp) -{ - int error; - - if (!bsp) { - fbsdrun_set_capabilities(vi->vcpu); - - /* - * Enable the 'unrestricted guest' mode for APs. - * - * APs startup in power-on 16-bit mode. - */ - error = vm_set_capability(vi->vcpu, VM_CAP_UNRESTRICTED_GUEST, 1); - assert(error == 0); - } - - fbsdrun_addcpu(vi); -} - static bool parse_config_option(const char *option) { @@ -787,17 +727,6 @@ } #endif -static void -set_defaults(void) -{ - - set_config_bool("acpi_tables", true); - set_config_bool("acpi_tables_in_memory", true); - set_config_value("memory.size", "256M"); - set_config_bool("x86.strictmsr", true); - set_config_value("lpc.fwcfg", "bhyve"); -} - int main(int argc, char *argv[]) { @@ -814,8 +743,8 @@ restore_file = NULL; #endif - init_config(); - set_defaults(); + bhyve_init_config(); + progname = basename(argv[0]); #ifdef BHYVE_SNAPSHOT @@ -825,9 +754,11 @@ #endif while ((c = getopt(argc, argv, optstr)) != -1) { switch (c) { +#ifdef __amd64__ case 'a': set_config_bool("x86.x2apic", false); break; +#endif case 'A': /* * NOP. For backward compatibility. Most systems don't @@ -903,6 +834,7 @@ if (!parse_config_option(optarg)) errx(EX_USAGE, "invalid configuration option '%s'", optarg); break; +#ifdef __amd64__ case 'H': set_config_bool("x86.vmexit_on_hlt", true); break; @@ -921,7 +853,6 @@ case 'e': set_config_bool("x86.strictio", true); break; -#ifdef __amd64__ case 'u': set_config_bool("rtc.use_localtime", false); break; @@ -929,16 +860,18 @@ case 'U': set_config_value("uuid", optarg); break; +#ifdef __amd64__ case 'w': set_config_bool("x86.strictmsr", false); break; +#endif case 'W': set_config_bool("virtio_msix", false); break; +#ifdef __amd64__ case 'x': set_config_bool("x86.x2apic", true); break; -#ifdef __amd64__ case 'Y': set_config_bool("x86.mptable", false); break; @@ -1012,7 +945,7 @@ exit(4); } - fbsdrun_set_capabilities(bsp); + bhyve_init_vcpu(bsp); /* Allocate per-VCPU resources. */ vcpu_info = calloc(guest_ncpus, sizeof(*vcpu_info)); @@ -1103,23 +1036,11 @@ init_gdb(ctx); #endif -#ifdef __amd64__ - if (lpc_bootrom()) { - if (vm_set_capability(bsp, VM_CAP_UNRESTRICTED_GUEST, 1)) { - fprintf(stderr, "ROM boot failed: unrestricted guest " - "capability not available\n"); - exit(4); - } - error = vcpu_reset(bsp); - assert(error == 0); - } -#endif - /* * Add all vCPUs. */ for (int vcpuid = 0; vcpuid < guest_ncpus; vcpuid++) - spinup_vcpu(&vcpu_info[vcpuid], vcpuid == BSP); + bhyve_start_vcpu(vcpu_info[vcpuid].vcpu, vcpuid == BSP); #ifdef BHYVE_SNAPSHOT if (restore_file != NULL) {