Changeset View
Changeset View
Standalone View
Standalone View
head/usr.sbin/bhyve/bhyverun.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include <vmmapi.h> | #include <vmmapi.h> | ||||
#include "bhyverun.h" | #include "bhyverun.h" | ||||
#include "acpi.h" | #include "acpi.h" | ||||
#include "atkbdc.h" | #include "atkbdc.h" | ||||
#include "inout.h" | #include "inout.h" | ||||
#include "dbgport.h" | #include "dbgport.h" | ||||
#include "fwctl.h" | #include "fwctl.h" | ||||
#include "gdb.h" | |||||
#include "ioapic.h" | #include "ioapic.h" | ||||
#include "mem.h" | #include "mem.h" | ||||
#include "mevent.h" | #include "mevent.h" | ||||
#include "mptbl.h" | #include "mptbl.h" | ||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "pci_irq.h" | #include "pci_irq.h" | ||||
#include "pci_lpc.h" | #include "pci_lpc.h" | ||||
#include "smbiostbl.h" | #include "smbiostbl.h" | ||||
▲ Show 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | fbsdrun_start_thread(void *param) | ||||
int vcpu; | int vcpu; | ||||
mtp = param; | mtp = param; | ||||
vcpu = mtp->mt_vcpu; | vcpu = mtp->mt_vcpu; | ||||
snprintf(tname, sizeof(tname), "vcpu %d", vcpu); | snprintf(tname, sizeof(tname), "vcpu %d", vcpu); | ||||
pthread_set_name_np(mtp->mt_thr, tname); | pthread_set_name_np(mtp->mt_thr, tname); | ||||
gdb_cpu_add(vcpu); | |||||
vm_loop(mtp->mt_ctx, vcpu, vmexit[vcpu].rip); | vm_loop(mtp->mt_ctx, vcpu, vmexit[vcpu].rip); | ||||
/* not reached */ | /* not reached */ | ||||
exit(1); | exit(1); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) | vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) | ||||
{ | { | ||||
assert(vmexit->inst_length == 0); | assert(vmexit->inst_length == 0); | ||||
stats.vmexit_mtrap++; | stats.vmexit_mtrap++; | ||||
gdb_cpu_mtrap(*pvcpu); | |||||
return (VMEXIT_CONTINUE); | return (VMEXIT_CONTINUE); | ||||
} | } | ||||
static int | static int | ||||
vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) | vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) | ||||
{ | { | ||||
int err, i; | int err, i; | ||||
struct vie *vie; | struct vie *vie; | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | case VM_SUSPEND_TRIPLEFAULT: | ||||
exit(3); | exit(3); | ||||
default: | default: | ||||
fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how); | fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how); | ||||
exit(100); | exit(100); | ||||
} | } | ||||
return (0); /* NOTREACHED */ | return (0); /* NOTREACHED */ | ||||
} | } | ||||
static int | |||||
vmexit_debug(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) | |||||
{ | |||||
gdb_cpu_suspend(*pvcpu); | |||||
return (VMEXIT_CONTINUE); | |||||
} | |||||
static vmexit_handler_t handler[VM_EXITCODE_MAX] = { | static vmexit_handler_t handler[VM_EXITCODE_MAX] = { | ||||
[VM_EXITCODE_INOUT] = vmexit_inout, | [VM_EXITCODE_INOUT] = vmexit_inout, | ||||
[VM_EXITCODE_INOUT_STR] = vmexit_inout, | [VM_EXITCODE_INOUT_STR] = vmexit_inout, | ||||
[VM_EXITCODE_VMX] = vmexit_vmx, | [VM_EXITCODE_VMX] = vmexit_vmx, | ||||
[VM_EXITCODE_SVM] = vmexit_svm, | [VM_EXITCODE_SVM] = vmexit_svm, | ||||
[VM_EXITCODE_BOGUS] = vmexit_bogus, | [VM_EXITCODE_BOGUS] = vmexit_bogus, | ||||
[VM_EXITCODE_REQIDLE] = vmexit_reqidle, | [VM_EXITCODE_REQIDLE] = vmexit_reqidle, | ||||
[VM_EXITCODE_RDMSR] = vmexit_rdmsr, | [VM_EXITCODE_RDMSR] = vmexit_rdmsr, | ||||
[VM_EXITCODE_WRMSR] = vmexit_wrmsr, | [VM_EXITCODE_WRMSR] = vmexit_wrmsr, | ||||
[VM_EXITCODE_MTRAP] = vmexit_mtrap, | [VM_EXITCODE_MTRAP] = vmexit_mtrap, | ||||
[VM_EXITCODE_INST_EMUL] = vmexit_inst_emul, | [VM_EXITCODE_INST_EMUL] = vmexit_inst_emul, | ||||
[VM_EXITCODE_SPINUP_AP] = vmexit_spinup_ap, | [VM_EXITCODE_SPINUP_AP] = vmexit_spinup_ap, | ||||
[VM_EXITCODE_SUSPENDED] = vmexit_suspend, | [VM_EXITCODE_SUSPENDED] = vmexit_suspend, | ||||
[VM_EXITCODE_TASK_SWITCH] = vmexit_task_switch, | [VM_EXITCODE_TASK_SWITCH] = vmexit_task_switch, | ||||
[VM_EXITCODE_DEBUG] = vmexit_debug, | |||||
}; | }; | ||||
static void | static void | ||||
vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) | vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) | ||||
{ | { | ||||
int error, rc; | int error, rc; | ||||
enum vm_exitcode exitcode; | enum vm_exitcode exitcode; | ||||
cpuset_t active_cpus; | cpuset_t active_cpus; | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | #endif | ||||
if (error) | if (error) | ||||
errx(EX_OSERR, "vm_set_topology"); | errx(EX_OSERR, "vm_set_topology"); | ||||
return (ctx); | return (ctx); | ||||
} | } | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
int c, error, gdb_port, err, bvmcons; | int c, error, dbg_port, gdb_port, err, bvmcons; | ||||
int max_vcpus, mptgen, memflags; | int max_vcpus, mptgen, memflags; | ||||
int rtc_localtime; | int rtc_localtime; | ||||
bool gdb_stop; | |||||
struct vmctx *ctx; | struct vmctx *ctx; | ||||
uint64_t rip; | uint64_t rip; | ||||
size_t memsize; | size_t memsize; | ||||
char *optstr; | char *optstr; | ||||
bvmcons = 0; | bvmcons = 0; | ||||
progname = basename(argv[0]); | progname = basename(argv[0]); | ||||
dbg_port = 0; | |||||
gdb_port = 0; | gdb_port = 0; | ||||
gdb_stop = false; | |||||
guest_ncpus = 1; | guest_ncpus = 1; | ||||
sockets = cores = threads = 1; | sockets = cores = threads = 1; | ||||
maxcpus = 0; | maxcpus = 0; | ||||
memsize = 256 * MB; | memsize = 256 * MB; | ||||
mptgen = 1; | mptgen = 1; | ||||
rtc_localtime = 1; | rtc_localtime = 1; | ||||
memflags = 0; | memflags = 0; | ||||
optstr = "abehuwxACHIPSWYp:g:c:s:m:l:U:"; | optstr = "abehuwxACHIPSWYp:g:G:c:s:m:l:U:"; | ||||
while ((c = getopt(argc, argv, optstr)) != -1) { | while ((c = getopt(argc, argv, optstr)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'a': | case 'a': | ||||
x2apic_mode = 0; | x2apic_mode = 0; | ||||
break; | break; | ||||
case 'A': | case 'A': | ||||
acpi = 1; | acpi = 1; | ||||
break; | break; | ||||
Show All 11 Lines | case 'p': | ||||
errx(EX_USAGE, "invalid cpu topology " | errx(EX_USAGE, "invalid cpu topology " | ||||
"'%s'", optarg); | "'%s'", optarg); | ||||
} | } | ||||
break; | break; | ||||
case 'C': | case 'C': | ||||
memflags |= VM_MEM_F_INCORE; | memflags |= VM_MEM_F_INCORE; | ||||
break; | break; | ||||
case 'g': | case 'g': | ||||
dbg_port = atoi(optarg); | |||||
break; | |||||
case 'G': | |||||
if (optarg[0] == 'w') { | |||||
gdb_stop = true; | |||||
optarg++; | |||||
} | |||||
gdb_port = atoi(optarg); | gdb_port = atoi(optarg); | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
if (lpc_device_parse(optarg) != 0) { | if (lpc_device_parse(optarg) != 0) { | ||||
errx(EX_USAGE, "invalid lpc device " | errx(EX_USAGE, "invalid lpc device " | ||||
"configuration '%s'", optarg); | "configuration '%s'", optarg); | ||||
} | } | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | main(int argc, char *argv[]) | ||||
sci_init(ctx); | sci_init(ctx); | ||||
/* | /* | ||||
* Exit if a device emulation finds an error in its initilization | * Exit if a device emulation finds an error in its initilization | ||||
*/ | */ | ||||
if (init_pci(ctx) != 0) | if (init_pci(ctx) != 0) | ||||
exit(1); | exit(1); | ||||
if (dbg_port != 0) | |||||
init_dbgport(dbg_port); | |||||
if (gdb_port != 0) | if (gdb_port != 0) | ||||
init_dbgport(gdb_port); | init_gdb(ctx, gdb_port, gdb_stop); | ||||
if (bvmcons) | if (bvmcons) | ||||
init_bvmcons(); | init_bvmcons(); | ||||
if (lpc_bootrom()) { | if (lpc_bootrom()) { | ||||
if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) { | if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) { | ||||
fprintf(stderr, "ROM boot failed: unrestricted guest " | fprintf(stderr, "ROM boot failed: unrestricted guest " | ||||
"capability not available\n"); | "capability not available\n"); | ||||
▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines |