Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyvectl/bhyvectl.c
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | usage(bool cpu_intel) | ||||
(void)fprintf(stderr, | (void)fprintf(stderr, | ||||
"Usage: %s --vm=<vmname>\n" | "Usage: %s --vm=<vmname>\n" | ||||
" [--cpu=<vcpu_number>]\n" | " [--cpu=<vcpu_number>]\n" | ||||
" [--create]\n" | " [--create]\n" | ||||
" [--destroy]\n" | " [--destroy]\n" | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
" [--checkpoint=<filename>]\n" | " [--checkpoint=<filename>]\n" | ||||
" [--suspend=<filename>]\n" | " [--suspend=<filename>]\n" | ||||
" [--migrate=<host>,<port>]\n" | |||||
" [--migrate-live=<host,port>]\n" | |||||
#endif | #endif | ||||
" [--get-all]\n" | " [--get-all]\n" | ||||
" [--get-stats]\n" | " [--get-stats]\n" | ||||
" [--set-desc-ds]\n" | " [--set-desc-ds]\n" | ||||
" [--get-desc-ds]\n" | " [--get-desc-ds]\n" | ||||
" [--set-desc-es]\n" | " [--set-desc-es]\n" | ||||
" [--get-desc-es]\n" | " [--get-desc-es]\n" | ||||
" [--set-desc-gs]\n" | " [--set-desc-gs]\n" | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
static int set_x2apic_state, get_x2apic_state; | static int set_x2apic_state, get_x2apic_state; | ||||
enum x2apic_state x2apic_state; | enum x2apic_state x2apic_state; | ||||
static int unassign_pptdev, bus, slot, func; | static int unassign_pptdev, bus, slot, func; | ||||
static int run; | static int run; | ||||
static int get_cpu_topology; | static int get_cpu_topology; | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
static int vm_checkpoint_opt; | static int vm_checkpoint_opt; | ||||
static int vm_suspend_opt; | static int vm_suspend_opt; | ||||
static int vm_migrate; | |||||
static int vm_migrate_live; | |||||
#endif | #endif | ||||
/* | /* | ||||
* VMCB specific. | * VMCB specific. | ||||
*/ | */ | ||||
static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl; | static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl; | ||||
static int get_vmcb_virq, get_avic_table; | static int get_vmcb_virq, get_avic_table; | ||||
▲ Show 20 Lines • Show All 275 Lines • ▼ Show 20 Lines | enum { | ||||
GET_GPA_PMAP, | GET_GPA_PMAP, | ||||
ASSERT_LAPIC_LVT, | ASSERT_LAPIC_LVT, | ||||
SET_RTC_TIME, | SET_RTC_TIME, | ||||
SET_RTC_NVRAM, | SET_RTC_NVRAM, | ||||
RTC_NVRAM_OFFSET, | RTC_NVRAM_OFFSET, | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
SET_CHECKPOINT_FILE, | SET_CHECKPOINT_FILE, | ||||
SET_SUSPEND_FILE, | SET_SUSPEND_FILE, | ||||
MIGRATE_VM, | |||||
MIGRATE_VM_LIVE, | |||||
#endif | #endif | ||||
}; | }; | ||||
static void | static void | ||||
print_cpus(const char *banner, const cpuset_t *cpus) | print_cpus(const char *banner, const cpuset_t *cpus) | ||||
{ | { | ||||
int i, first; | int i, first; | ||||
▲ Show 20 Lines • Show All 856 Lines • ▼ Show 20 Lines | const struct option common_opts[] = { | ||||
{ "force-poweroff", NO_ARG, &force_poweroff, 1 }, | { "force-poweroff", NO_ARG, &force_poweroff, 1 }, | ||||
{ "get-active-cpus", NO_ARG, &get_active_cpus, 1 }, | { "get-active-cpus", NO_ARG, &get_active_cpus, 1 }, | ||||
{ "get-suspended-cpus", NO_ARG, &get_suspended_cpus, 1 }, | { "get-suspended-cpus", NO_ARG, &get_suspended_cpus, 1 }, | ||||
{ "get-intinfo", NO_ARG, &get_intinfo, 1 }, | { "get-intinfo", NO_ARG, &get_intinfo, 1 }, | ||||
{ "get-cpu-topology", NO_ARG, &get_cpu_topology, 1 }, | { "get-cpu-topology", NO_ARG, &get_cpu_topology, 1 }, | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
{ "checkpoint", REQ_ARG, 0, SET_CHECKPOINT_FILE}, | { "checkpoint", REQ_ARG, 0, SET_CHECKPOINT_FILE}, | ||||
{ "suspend", REQ_ARG, 0, SET_SUSPEND_FILE}, | { "suspend", REQ_ARG, 0, SET_SUSPEND_FILE}, | ||||
{ "migrate", REQ_ARG, 0, MIGRATE_VM}, | |||||
{ "migrate-live", REQ_ARG, 0, MIGRATE_VM_LIVE}, | |||||
#endif | #endif | ||||
}; | }; | ||||
const struct option intel_opts[] = { | const struct option intel_opts[] = { | ||||
{ "get-vmcs-pinbased-ctls", | { "get-vmcs-pinbased-ctls", | ||||
NO_ARG, &get_pinbased_ctls, 1 }, | NO_ARG, &get_pinbased_ctls, 1 }, | ||||
{ "get-vmcs-procbased-ctls", | { "get-vmcs-procbased-ctls", | ||||
NO_ARG, &get_procbased_ctls, 1 }, | NO_ARG, &get_procbased_ctls, 1 }, | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | snapshot_request(struct vmctx *ctx, const char *file, enum ipc_opcode code) | ||||
imsg.code = code; | imsg.code = code; | ||||
strlcpy(imsg.data.op.snapshot_filename, file, MAX_SNAPSHOT_FILENAME); | strlcpy(imsg.data.op.snapshot_filename, file, MAX_SNAPSHOT_FILENAME); | ||||
length = offsetof(struct ipc_message, data) + sizeof(imsg.data.op); | length = offsetof(struct ipc_message, data) + sizeof(imsg.data.op); | ||||
return (send_message(ctx, (void *)&imsg, length)); | return (send_message(ctx, (void *)&imsg, length)); | ||||
} | } | ||||
static int | |||||
send_start_migrate(struct vmctx *ctx, const char *migrate_vm, bool live) | |||||
{ | |||||
struct ipc_message imsg; | |||||
char *hostname, *pos; | |||||
size_t length; | |||||
int rc; | |||||
if (live) | |||||
imsg.code = START_MIGRATE_LIVE; | |||||
else | |||||
imsg.code = START_MIGRATE; | |||||
memset(imsg.data.op.migrate_req.host, 0, MAX_HOSTNAME_LEN); | |||||
hostname = strdup(migrate_vm); | |||||
if ((pos = strchr(hostname, ',')) != NULL ) { | |||||
*pos = '\0'; | |||||
strlcpy(imsg.data.op.migrate_req.host, hostname, MAX_HOSTNAME_LEN); | |||||
pos = pos + 1; | |||||
rc = sscanf(pos, "%d", &(imsg.data.op.migrate_req.port)); | |||||
if (rc == 0) { | |||||
fprintf(stderr, "Could not parse the port\r\n"); | |||||
free(hostname); | |||||
return -1; | |||||
} | |||||
} else { | |||||
strlcpy(imsg.data.op.migrate_req.host, hostname, MAX_HOSTNAME_LEN); | |||||
/* If only one variable could be read, it should be the host */ | |||||
imsg.data.op.migrate_req.port = DEFAULT_MIGRATION_PORT; | |||||
} | |||||
free(hostname); | |||||
length = offsetof(struct ipc_message, data) + sizeof(imsg.data.op); | |||||
return (send_message(ctx, (void *)&imsg, length)); | |||||
} | |||||
#endif | #endif | ||||
int | int | ||||
main(int argc, char *argv[]) | main(int argc, char *argv[]) | ||||
{ | { | ||||
char *vmname; | char *vmname; | ||||
int error, ch, vcpu, ptenum; | int error, ch, vcpu, ptenum; | ||||
vm_paddr_t gpa_pmap; | vm_paddr_t gpa_pmap; | ||||
struct vm_exit vmexit; | struct vm_exit vmexit; | ||||
uint64_t rax, cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7; | uint64_t rax, cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7; | ||||
uint64_t rsp, rip, rflags, efer, pat; | uint64_t rsp, rip, rflags, efer, pat; | ||||
uint64_t eptp, bm, addr, u64, pteval[4], *pte, info[2]; | uint64_t eptp, bm, addr, u64, pteval[4], *pte, info[2]; | ||||
struct vmctx *ctx; | struct vmctx *ctx; | ||||
cpuset_t cpus; | cpuset_t cpus; | ||||
bool cpu_intel; | bool cpu_intel; | ||||
uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; | uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; | ||||
struct tm tm; | struct tm tm; | ||||
struct option *opts; | struct option *opts; | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
char *checkpoint_file, *suspend_file; | char *checkpoint_file, *suspend_file, *migrate_host; | ||||
#endif | #endif | ||||
cpu_intel = cpu_vendor_intel(); | cpu_intel = cpu_vendor_intel(); | ||||
opts = setup_options(cpu_intel); | opts = setup_options(cpu_intel); | ||||
vcpu = 0; | vcpu = 0; | ||||
vmname = NULL; | vmname = NULL; | ||||
assert_lapic_lvt = -1; | assert_lapic_lvt = -1; | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | #ifdef BHYVE_SNAPSHOT | ||||
case SET_CHECKPOINT_FILE: | case SET_CHECKPOINT_FILE: | ||||
vm_checkpoint_opt = 1; | vm_checkpoint_opt = 1; | ||||
checkpoint_file = optarg; | checkpoint_file = optarg; | ||||
break; | break; | ||||
case SET_SUSPEND_FILE: | case SET_SUSPEND_FILE: | ||||
vm_suspend_opt = 1; | vm_suspend_opt = 1; | ||||
suspend_file = optarg; | suspend_file = optarg; | ||||
break; | break; | ||||
case MIGRATE_VM: | |||||
vm_migrate = 1; | |||||
migrate_host = optarg; | |||||
break; | |||||
case MIGRATE_VM_LIVE: | |||||
vm_migrate_live = 1; | |||||
migrate_host = optarg; | |||||
break; | |||||
#endif | #endif | ||||
default: | default: | ||||
usage(cpu_intel); | usage(cpu_intel); | ||||
} | } | ||||
} | } | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
▲ Show 20 Lines • Show All 462 Lines • ▼ Show 20 Lines | if (!error && destroy) | ||||
vm_destroy(ctx); | vm_destroy(ctx); | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
if (!error && vm_checkpoint_opt) | if (!error && vm_checkpoint_opt) | ||||
error = snapshot_request(ctx, checkpoint_file, START_CHECKPOINT); | error = snapshot_request(ctx, checkpoint_file, START_CHECKPOINT); | ||||
if (!error && vm_suspend_opt) | if (!error && vm_suspend_opt) | ||||
error = snapshot_request(ctx, suspend_file, START_SUSPEND); | error = snapshot_request(ctx, suspend_file, START_SUSPEND); | ||||
if (!error && vm_migrate) | |||||
error = send_start_migrate(ctx, migrate_host, false); | |||||
if (!error && vm_migrate_live) | |||||
error = send_start_migrate(ctx, migrate_host, true); | |||||
#endif | #endif | ||||
free (opts); | free (opts); | ||||
exit(error); | exit(error); | ||||
} | } |