int main(int argc, char *argv[]) { VM *vm = vm_create(hello, sizeof(hello), 0); vm_exec(vm, 0, false); vm_free(vm); // int t1 = (clock() / (CLOCKS_PER_SEC / 1000)); vm = vm_create(loop, sizeof(loop), 2); vm_exec(vm, 0, false); vm_print_data(vm->globals, vm->nglobals); vm_free(vm); // int t2 = (clock() / (CLOCKS_PER_SEC / 1000)); vm = vm_create(factorial, sizeof(factorial), 0); vm_exec(vm, 23, false); vm_free(vm); vm = vm_create(f, sizeof(f), 0); vm_exec(vm, 0, false); vm_free(vm); // printf("duration = %d ms\n", (t2 - t1)); return 0; }
int main(void){ struct virtual_machine * vm; unsigned int output; unsigned char c; struct termios * original = terminal_setup(); vm = vm_create(data_start, data_end, data); while(!is_halted(vm)){ if(vm_getc(vm, &output)){ putchar((int)output); fflush(stdout); } if(read(STDIN_FILENO, &c, 1) > 0){ vm_putc(vm, c); } step(vm); } vm_destroy(vm); tcsetattr(STDOUT_FILENO,TCSANOW, original); tcsetattr(STDOUT_FILENO,TCSAFLUSH, original); free(original); return 0; }
/* Create a router instance */ vm_instance_t *create_instance (char *configure_filename) { adm5120_t *adm5120; char *name; if (!(adm5120 = malloc (sizeof (*adm5120)))) { fprintf (stderr, "ADM5120': Unable to create new instance!\n"); return NULL; } memset (adm5120, 0, sizeof (*adm5120)); name = strdup ("adm5120"); if (!(adm5120->vm = vm_create (name, VM_TYPE_ADM5120))) { fprintf (stderr, "ADM5120 : unable to create VM instance!\n"); goto err_vm; } free (name); if (configure_filename != NULL) adm5120->vm->configure_filename = strdup (configure_filename); adm5120_init_defaults (adm5120); adm5120_parse_configure (adm5120); /*init gdb debug */ vm_debug_init (adm5120->vm); adm5120->vm->hw_data = adm5120; return (adm5120->vm); err_vm: free (adm5120); return NULL; }
int _vm_create(const char *name) { int error = vm_create(name); if (error) rb_raise(rb_eException, "vm_create failed"); return error; }
void __init start_vmm ( const struct multiboot_info *mbi ) { //Initialize serial port COM1, this must be done before calling outf setup_serial(); outf("\n\n\n!!!!!!!!!!!BEGIN!!!!!!!!!!!\n\n\n"); //Parse the command line that user pass to GRUB struct cmdline_option opt = parse_cmdline ( mbi ); //Set up memory layout and store the layout in pml struct pmem_layout pml; setup_memory(mbi, &opt, &pml); struct vm_info vm; vm_create (&vm, pml.vmm_pmem_start, opt.vmm_pmem_size, &(pml.e820)); outf("\n++++++ New virtual machine created. Going to start the VM\n"); vm_init (&vm); //Debug //e820_print_map(&(pml.e820)); outf ("\n++++++ Going to GRUB for the 2nd time\n"); vm_boot (&vm); }
struct _vm * vm_load (const char * filename) { unsigned char * mem; FILE * fh; size_t filesize; struct _vm * vm; fh = fopen(filename, "rb"); if (fh == NULL) return NULL; fseek(fh, 0, SEEK_END); filesize = ftell(fh); fseek(fh, 0, SEEK_SET); mem = (unsigned char *) malloc(VM_MEMSIZE); memset(mem, 0, VM_MEMSIZE); fread(mem, 1, filesize, fh); fclose(fh); vm = vm_create(mem); free(mem); return vm; }
int main(int argc, char *argv[]) { rpc_init(); RPCSession* session = rpc_session(); if(!session) { printf("RPC server not connected\n"); return ERROR_RPC_DISCONNECTED; } rpc = rpc_connect(session->host, session->port, 3, true); if(rpc == NULL) { printf("Failed to connect RPC server\n"); return ERROR_RPC_DISCONNECTED; } int rc; if((rc = vm_create(argc, argv))) { printf("Failed to create VM. Error code : %d\n", rc); rpc_disconnect(rpc); return ERROR_CMD_EXECUTE; } while(1) { if(rpc_connected(rpc)) { rpc_loop(rpc); } else { free(rpc); break; } } return 0; }
int repl(){ char *a = calloc(1, 1000 * sizeof(char)); xenon_stack_vector stack; stack.size = 1000; while(1){ stack.vector = calloc(1, 1000 * sizeof(xenon_stack_item)); printf("Xenon> "); input(a, 1000); if(strcmp(a, ".exit") == 0){ return 0; } char *b = preprocessor(a); mpc_ast_t *ast = parse("stdin", b); free(b); if(ast != NULL){ stack.cursor = 0; mpc_ast_print(ast); //vm_add_opcode_to_stack(&stack, HALT); tree_walker(ast, stack); vm_add_opcode_to_stack(&stack, CONST); vm_add_int_to_stack(&stack, 10); printf("%i\n", stack.cursor); VM *vm = vm_create(stack, 0); mpc_ast_delete(ast); vm_exec(vm, 0, false); vm_free(vm); } if(stack.vector != NULL){ free(stack.vector); } } free(a); return 0; }
int main(void){ struct virtual_machine * vm; unsigned int output; unsigned char c; struct termios * original = terminal_setup(); vm = vm_create(data_start, data_end, data); printf("Kernel image has been loaded. All input is now being handled by the emulator.\n"); printf("Press 'q' to quit.\n"); while(!is_halted(vm)){ if(vm_getc(vm, &output)){ putchar((int)output); fflush(stdout); } if(read(STDIN_FILENO, &c, 1) > 0){ vm_putc(vm, c); } step(vm); } vm_destroy(vm); tcsetattr(STDOUT_FILENO,TCSANOW, original); tcsetattr(STDOUT_FILENO,TCSAFLUSH, original); free(original); return 0; }
/* Create an instance of the specified type */ vm_instance_t *vm_create_instance(char *name,int instance_id,char *type) { vm_platform_t *platform; vm_instance_t *vm = NULL; if (!(platform = vm_platform_find(type))) { fprintf(stderr,"VM %s: unknown platform '%s'\n",name,type); goto error; } /* Create a generic VM instance */ if (!(vm = vm_create(name,instance_id,platform))) goto error; /* Initialize specific parts */ if (vm->platform->create_instance(vm) == -1) goto error; return vm; error: fprintf(stderr,"VM %s: unable to create instance!\n",name); vm_free(vm); return NULL; }
static struct vmctx * do_open(const char *vmname) { struct vmctx *ctx; int error; bool reinit, romboot; reinit = romboot = false; if (lpc_bootrom()) romboot = true; error = vm_create(vmname); if (error) { if (errno == EEXIST) { if (romboot) { reinit = true; } else { /* * The virtual machine has been setup by the * userspace bootloader. */ } } else { perror("vm_create"); exit(1); } } else { if (!romboot) { /* * If the virtual machine was just created then a * bootrom must be configured to boot it. */ fprintf(stderr, "virtual machine cannot be booted\n"); exit(1); } } ctx = vm_open(vmname); if (ctx == NULL) { perror("vm_open"); exit(1); } if (reinit) { error = vm_reinit(ctx); if (error) { perror("vm_reinit"); exit(1); } } return (ctx); }
vm_t *bsr_convert(bsr_t *bsr, vm_type_t type) { vm_t *vm = NULL; int i; int j; int k; int l; switch (type) { /* Convert a BSR matrix to a DENSE matrix. */ case DEN: vm_create(&vm, DEN, 1, bsr->_.w, bsr->_.h); for (i = 0; i < bsr->bc * bsr->bs * bsr->bs; i++) { _s_debugf(BSR_DEBUG, "i=%d v="DPF"\n", i, bsr->v[i]); } for (i = 0; i < ((bsr->_.h / bsr->bs) + 1); i++) { _s_debugf(BSR_DEBUG, "i=%d, rp=%d\n", i, bsr->rp[i]); } for (i = 0; i < bsr->bc; i++) { _s_debugf(BSR_DEBUG, "i=%d, ci=%d\n", i, bsr->ci[i]); } for (i = 0; i < (bsr->_.h / bsr->bs); i++) { _s_debugf(BSR_DEBUG, "cvt i=%d\n", i); for (j = bsr->rp[i]; j < bsr->rp[i + 1]; j++) { _s_debugf(BSR_DEBUG, "cvt j=%d col=%d\n", j, bsr->ci[j]); for (k = 0; k < bsr->bs; k++) { for (l = 0; l < bsr->bs; l++) { _s_debugf(BSR_DEBUG, "c[%d][%d]="DPF"\n", (i * bsr->bs) + k, (j * bsr->bs) + l, bsr->v[j * (bsr->bs * bsr->bs) + (k * bsr->bs) + l]); ((den_matrix_t *) vm)->v /**/ [(i * bsr->bs) + k] /**/ [(bsr->ci[j] * bsr->bs) + l] = /**/ bsr->v[j * (bsr->bs * bsr->bs) + (k * bsr->bs) + l]; } } } } break; default: fdie("unknown format to convert %d\n", type); break; } return vm; }
void start_hypervisor() { int i; uint8_t nr_vcpus = 1; // TODO: It will be read from configuration file. uint32_t pcpu = smp_processor_id(); if (pcpu == 0) { timemanager_init(); sched_init(); vm_setup(); for (i = 0; i < NUM_GUESTS_STATIC; i++) { vmid_t vmid; if ((vmid = vm_create(nr_vcpus)) == VM_CREATE_FAILED) { printf("vm_create(vm[%d]) is failed\n", i); goto error; } if (vm_init(vmid) != HALTED) { printf("vm_init(vm[%d]) is failed\n", i); goto error; } if (vm_start(vmid) != RUNNING) { printf("vm_start(vm[%d]) is failed\n", i); goto error; } } smp_pen = 1; } else { while (!smp_pen) ; printf("cpu[%d] is enabled\n", pcpu); } /* * TODO: Add a function - return vmid or vcpu_id to execute for the first time. * TODO: Rename guest_sched_start to do_schedule or something others. * do_schedule(vmid) or do_schedule(vcpu_id) */ printf("sched_start!!!\n"); sched_start(); /* The code flow must not reach here */ error: printf("-------- [%s] ERROR: K-Hypervisor must not reach here\n", __func__); abort(); }
void ddbg_create_vm() { breakpoints = breakpoint_list_create(); list_init(&backtrace); list_attributes_copy(&backtrace, list_meter_uint16_t, 1); ignore_next_breakpoint = false; vm = vm_create(); vm_hook_register(vm, &ddbg_precycle_hook, HOOK_ON_PRE_CYCLE, NULL); vm_hook_register(vm, &ddbg_postcycle_hook, HOOK_ON_POST_CYCLE, NULL); vm_hook_register(vm, &ddbg_write_hook, HOOK_ON_WRITE, NULL); vm_hook_register(vm, &ddbg_break_hook, HOOK_ON_BREAK, NULL); vm_hook_register(vm, &ddbg_interrupt_hook, HOOK_ON_INTERRUPT, NULL); vm_hook_register(vm, &ddbg_hardware_change_hook, HOOK_ON_HARDWARE_CHANGE, NULL); vm_hook_register(vm, &ddbg_send_vm_state, HOOK_ON_60HZ, NULL); printd(LEVEL_DEFAULT, "Created VM.\n"); }
vm_t *kat_convert(kat_matrix_t *kat, vm_type_t type) { vm_t *vm = NULL; switch (type) { case DEN: vm_create(&vm, DEN, 1, kat->_.w, kat->_.h); kat_node_to_dense(kat, kat->root, (den_matrix_t *) vm); break; default: fdie("unknown format to convert %d\n", type); break; } /* XXX: */ /* qdt->_.f.free(qdt); */ return vm; }
int xh_vm_create(void) { int error; if (vm != NULL) { return (EEXIST); } error = vmm_init(); if (error != 0) { return (error); } memflags = 0; lowmem_limit = (3ull << 30); return (vm_create(&vm)); }
int main_continued(void) { vm_t vm; int err; /* setup for restart with a setjmp */ while (setjmp(restart_jmp_buf) != 0) { reset_resources(); } restart_tcb = camkes_get_tls()->tcb_cap; restart_event_reg_callback(restart_event, NULL); err = vmm_init(); assert(!err); print_cpio_info(); /* Create the VM */ err = vm_create(VM_NAME, VM_PRIO, _fault_endpoint, VM_BADGE, &_vka, &_simple, &_vspace, &_io_ops, &vm); if (err) { printf("Failed to create VM\n"); seL4_DebugHalt(); return -1; } /* HACK: See if we have a "RAM device" for 1-1 mappings */ map_unity_ram(&vm); /* Load system images */ printf("Loading Linux: \'%s\' dtb: \'%s\'\n", VM_LINUX_NAME, VM_LINUX_DTB_NAME); err = load_linux(&vm, VM_LINUX_NAME, VM_LINUX_DTB_NAME); if (err) { printf("Failed to load VM image\n"); seL4_DebugHalt(); return -1; } vm_vchan_setup(&vm); /* Power on */ printf("Starting VM\n\n"); err = vm_start(&vm); if (err) { printf("Failed to start VM\n"); seL4_DebugHalt(); return -1; } /* Loop forever, handling events */ while (1) { seL4_MessageInfo_t tag; seL4_Word sender_badge; tag = seL4_Wait(_fault_endpoint, &sender_badge); if (sender_badge == 0) { seL4_Word label; label = seL4_MessageInfo_get_label(tag); if (label == IRQ_MESSAGE_LABEL) { irq_server_handle_irq_ipc(_irq_server); } else { printf("Unknown label (%d) for IPC badge %d\n", label, sender_badge); } } else if (sender_badge == VUSB_NBADGE) { vusb_notify(); } else { assert(sender_badge == VM_BADGE); err = vm_event(&vm, tag); if (err) { /* Shutdown */ vm_stop(&vm); seL4_DebugHalt(); while (1); } } } return 0; }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; host_context_t* dtemu = malloc(sizeof(host_context_t)); const char* warnprefix = "no-"; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* headless_mode = arg_lit0("h", "headless", "Run machine witout displaying monitor and SPED output"); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_int* radiation = arg_intn("r", NULL, "<n>", 0, 1, "Radiation factor (higher is less radiation)"); struct arg_lit* catch_fire = arg_lit0("c", "catch-fire", "The virtual machine should catch fire instead of halting."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, warning_policies, debug_mode, execution_dump_file, terminate_mode, headless_mode, legacy_mode, little_endian_mode, radiation, catch_fire, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Show version information. version_print(bautofree(bfromcstr("Emulator"))); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Set up warning policies. dsetwarnpolicy(warning_policies); // Set up error handling. if (dsethalt()) { // Handle the error. dautohandle(); printd(LEVEL_ERROR, "emulator: error occurred.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) dhalt(ERR_EMU_LOAD_FILE_FAILED, input_file->filename[0]); } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read leading component. for (i = 0; i < strlen(ldata_objfmt); i++) leading[i] = fgetc(load); fseek(load, 0, SEEK_SET); // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) dhalt(ERR_INTERMEDIATE_EXECUTION, NULL); // Set up the host context. glfwInit(); dtemu->create_context = &dtemu_create_context; dtemu->activate_context = &dtemu_activate_context; dtemu->swap_buffers = &dtemu_swap_buffers; dtemu->destroy_context = &dtemu_destroy_context; dtemu->get_ud = &dtemu_get_ud; // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); // Set radiation and catch fire settings. if (radiation->count == 1) vm->radiation_factor = radiation->ival[0]; if (catch_fire->count == 1) vm->can_fire = true; // Init hardware. vm_hw_clock_init(vm); if (headless_mode->count < 1) vm->host = dtemu; vm_hw_sped3_init(vm); vm_hw_lem1802_init(vm); vm_hw_m35fd_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { for (i = 0; i < vm_hw_count(vm); i++) { hw_t* device = vm_hw_get_device(vm, i); if (device == NULL) continue; if (device->id == 0x7349F615 && device->manufacturer == 0x1C6C8B36) { vm_hw_lem1802_mem_set_screen((struct lem1802_hardware*)device->userdata, 0x8000); break; } } } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); glfwTerminate(); return 0; }
int grub_emu_bhyve_init(const char *name, grub_uint64_t memsz) { int err; int val; grub_uint64_t lomemsz; #ifdef VMMAPI_VERSION int need_reinit = 0; #endif err = vm_create (name); if (err != 0) { if (errno != EEXIST) { fprintf (stderr, "Could not create VM %s\n", name); return GRUB_ERR_ACCESS_DENIED; } #ifdef VMMAPI_VERSION need_reinit = 1; #endif } bhyve_ctx = vm_open (name); if (bhyve_ctx == NULL) { fprintf (stderr, "Could not open VM %s\n", name); return GRUB_ERR_BUG; } #ifdef VMMAPI_VERSION if (need_reinit) { err = vm_reinit (bhyve_ctx); if (err != 0) { fprintf (stderr, "Could not reinit VM %s\n", name); return GRUB_ERR_BUG; } } #endif val = 0; err = vm_get_capability (bhyve_ctx, 0, VM_CAP_UNRESTRICTED_GUEST, &val); if (err != 0) { fprintf (stderr, "VM unrestricted guest capability required\n"); return GRUB_ERR_BAD_DEVICE; } err = vm_set_capability (bhyve_ctx, 0, VM_CAP_UNRESTRICTED_GUEST, 1); if (err != 0) { fprintf (stderr, "Could not enable unrestricted guest for VM\n"); return GRUB_ERR_BUG; } err = vm_setup_memory (bhyve_ctx, memsz, VM_MMAP_ALL); if (err) { fprintf (stderr, "Could not setup memory for VM\n"); return GRUB_ERR_OUT_OF_MEMORY; } lomemsz = vm_get_lowmem_limit(bhyve_ctx); /* * Extract the virtual address of the mapped guest memory. */ if (memsz >= lomemsz) { bhyve_g2h.lomem = lomemsz; bhyve_g2h.himem = memsz - lomemsz; bhyve_g2h.himem_ptr = vm_map_gpa(bhyve_ctx, 4*GB, bhyve_g2h.himem); } else { bhyve_g2h.lomem = memsz; bhyve_g2h.himem = 0; } bhyve_g2h.lomem_ptr = vm_map_gpa(bhyve_ctx, 0, bhyve_g2h.lomem); /* * bhyve is going to return the following memory segments * * 0 - 640K - usable * 640K- 1MB - vga hole, BIOS, not usable. * 1MB - lomem - usable * lomem - 4G - not usable * 4G - himem - usable [optional if himem != 0] */ bhyve_info.nsegs = 2; bhyve_info.segs = bhyve_mm; bhyve_mm[0].start = 0x0; bhyve_mm[0].end = 640*1024 - 1; /* 640K */ bhyve_mm[0].type = GRUB_MEMORY_AVAILABLE; bhyve_mm[1].start = 1024*1024; bhyve_mm[1].end = (memsz > lomemsz) ? lomemsz : memsz; bhyve_mm[1].type = GRUB_MEMORY_AVAILABLE; if (memsz > lomemsz) { bhyve_info.nsegs++; bhyve_mm[2].start = 4*GB; bhyve_mm[2].end = (memsz - lomemsz) + bhyve_mm[2].start; bhyve_mm[2].type = GRUB_MEMORY_AVAILABLE; } /* The boot-code size is just the GDT that needs to be copied */ bhyve_info.bootsz = sizeof(bhyve_gdt); return 0; }
int dm_run(int argc, char *argv[]) { int c, error, err; int max_vcpus, mptgen; struct vmctx *ctx; size_t memsize; int option_idx = 0; progname = basename(argv[0]); guest_ncpus = 1; memsize = 256 * MB; mptgen = 1; if (signal(SIGHUP, sig_handler_term) == SIG_ERR) fprintf(stderr, "cannot register handler for SIGHUP\n"); if (signal(SIGINT, sig_handler_term) == SIG_ERR) fprintf(stderr, "cannot register handler for SIGINT\n"); while ((c = getopt_long(argc, argv, optstr, long_options, &option_idx)) != -1) { switch (c) { case 'A': acpi = 1; break; case 'p': if (pincpu_parse(optarg) != 0) { errx(EX_USAGE, "invalid vcpu pinning configuration '%s'", optarg); } break; case 'c': dm_strtoi(optarg, NULL, 0, &guest_ncpus); break; case 'E': if (acrn_parse_elf(optarg) != 0) exit(1); else break; break; case 'i': ioc_parse(optarg); break; case 'l': if (lpc_device_parse(optarg) != 0) { errx(EX_USAGE, "invalid lpc device configuration '%s'", optarg); } break; case 's': if (pci_parse_slot(optarg) != 0) exit(1); else break; case 'm': error = vm_parse_memsize(optarg, &memsize); if (error) errx(EX_USAGE, "invalid memsize '%s'", optarg); break; case 'U': guest_uuid_str = optarg; break; case 'W': virtio_msix = 0; break; case 'Y': mptgen = 0; break; case 'k': if (acrn_parse_kernel(optarg) != 0) exit(1); else break; case 'r': if (acrn_parse_ramdisk(optarg) != 0) exit(1); else break; case 'B': if (acrn_parse_bootargs(optarg) != 0) exit(1); else break; break; case 'G': if (acrn_parse_gvtargs(optarg) != 0) { errx(EX_USAGE, "invalid GVT param %s", optarg); exit(1); } break; case 'v': print_version(); break; case CMD_OPT_VSBL: if (high_bios_size() == 0 && acrn_parse_vsbl(optarg) != 0) { errx(EX_USAGE, "invalid vsbl param %s", optarg); exit(1); } break; case CMD_OPT_OVMF: if (!vsbl_file_name && acrn_parse_ovmf(optarg) != 0) { errx(EX_USAGE, "invalid ovmf param %s", optarg); exit(1); } break; case CMD_OPT_PART_INFO: if (acrn_parse_guest_part_info(optarg) != 0) { errx(EX_USAGE, "invalid guest partition info param %s", optarg); exit(1); } break; case CMD_OPT_TRUSTY_ENABLE: trusty_enabled = 1; break; case CMD_OPT_VIRTIO_POLL_ENABLE: if (acrn_parse_virtio_poll_interval(optarg) != 0) { errx(EX_USAGE, "invalid virtio poll interval %s", optarg); exit(1); } break; case CMD_OPT_MAC_SEED: strncpy(mac_seed_str, optarg, sizeof(mac_seed_str)); mac_seed_str[sizeof(mac_seed_str) - 1] = '\0'; mac_seed = mac_seed_str; break; case CMD_OPT_PTDEV_NO_RESET: ptdev_no_reset(true); break; case CMD_OPT_DEBUGEXIT: debugexit_enabled = true; break; case CMD_OPT_LAPIC_PT: lapic_pt = true; break; case CMD_OPT_VTPM2: if (acrn_parse_vtpm2(optarg) != 0) { errx(EX_USAGE, "invalid vtpm2 param %s", optarg); exit(1); } break; case CMD_OPT_INTR_MONITOR: if (acrn_parse_intr_monitor(optarg) != 0) { errx(EX_USAGE, "invalid intr-monitor params %s", optarg); exit(1); } break; case 'h': usage(0); default: usage(1); } } argc -= optind; argv += optind; if (argc != 1) usage(1); if (!check_hugetlb_support()) { fprintf(stderr, "check_hugetlb_support failed\n"); exit(1); } vmname = argv[0]; for (;;) { ctx = vm_create(vmname, (unsigned long)vhm_req_buf); if (!ctx) { perror("vm_open"); exit(1); } if (guest_ncpus < 1) { fprintf(stderr, "Invalid guest vCPUs (%d)\n", guest_ncpus); goto fail; } max_vcpus = num_vcpus_allowed(ctx); if (guest_ncpus > max_vcpus) { fprintf(stderr, "%d vCPUs requested but %d available\n", guest_ncpus, max_vcpus); goto fail; } err = vm_setup_memory(ctx, memsize); if (err) { fprintf(stderr, "Unable to setup memory (%d)\n", errno); goto fail; } err = mevent_init(); if (err) { fprintf(stderr, "Unable to initialize mevent (%d)\n", errno); goto mevent_fail; } if (vm_init_vdevs(ctx) < 0) { fprintf(stderr, "Unable to init vdev (%d)\n", errno); goto dev_fail; } /* * build the guest tables, MP etc. */ if (mptgen) { error = mptable_build(ctx, guest_ncpus); if (error) { goto vm_fail; } } error = smbios_build(ctx); if (error) goto vm_fail; if (acpi) { error = acpi_build(ctx, guest_ncpus); if (error) goto vm_fail; } error = acrn_sw_load(ctx); if (error) goto vm_fail; /* * Change the proc title to include the VM name. */ /*setproctitle("%s", vmname);*/ /* * Add CPU 0 */ error = add_cpu(ctx, guest_ncpus); if (error) goto vm_fail; /* Make a copy for ctx */ _ctx = ctx; /* * Head off to the main event dispatch loop */ mevent_dispatch(); vm_pause(ctx); delete_cpu(ctx, BSP); if (vm_get_suspend_mode() != VM_SUSPEND_FULL_RESET) break; vm_deinit_vdevs(ctx); mevent_deinit(); vm_unsetup_memory(ctx); vm_destroy(ctx); _ctx = 0; vm_set_suspend_mode(VM_SUSPEND_NONE); } vm_fail: vm_deinit_vdevs(ctx); dev_fail: mevent_deinit(); mevent_fail: vm_unsetup_memory(ctx); fail: vm_destroy(ctx); exit(0); }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, debug_mode, execution_dump_file, terminate_mode, legacy_mode, little_endian_mode, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Emulator"))); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) { fprintf(stderr, "emulator: unable to load %s from disk.\n", argv[1]); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) { fprintf(stderr, "emulator: it appears you passed intermediate code for execution. link\n"); fprintf(stderr, " the input code with the toolchain linker to execute it.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); vm_hw_timer_init(vm); vm_hw_io_init(vm); vm_hw_lem1802_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { vm_hw_lem1802_mem_set_screen(vm, 0x8000); vm_hw_io_set_legacy(true); } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); #ifdef __EMSCRIPTEN__ printd(LEVEL_WARNING, "warning: not cleaning up resources in Emscripten.\n"); #else if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_hw_timer_free(vm); vm_hw_io_free(vm); vm_hw_lem1802_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 0; #endif }
static vm_map_t do_fork(vm_map_t org_map) { vm_map_t new_map; struct region *tmp, *src, *dest; int map_type; if ((new_map = vm_create()) == NULL) return NULL; /* * Copy all regions */ tmp = &new_map->head; src = &org_map->head; /* * Copy top region */ *tmp = *src; tmp->next = tmp->prev = tmp; if (src == src->next) /* Blank memory ? */ return new_map; do { ASSERT(src != NULL); ASSERT(src->next != NULL); if (src == &org_map->head) { dest = tmp; } else { /* Create new region struct */ dest = kmem_alloc(sizeof(*dest)); if (dest == NULL) return NULL; *dest = *src; /* memcpy */ dest->prev = tmp; dest->next = tmp->next; tmp->next->prev = dest; tmp->next = dest; tmp = dest; } if (src->flags == REG_FREE) { /* * Skip free region */ } else { /* Check if the region can be shared */ if (!(src->flags & REG_WRITE) && !(src->flags & REG_MAPPED)) { dest->flags |= REG_SHARED; } if (!(dest->flags & REG_SHARED)) { /* Allocate new physical page. */ dest->phys = page_alloc(src->size); if (dest->phys == 0) return NULL; /* Copy source page */ memcpy(phys_to_virt(dest->phys), phys_to_virt(src->phys), src->size); } /* Map the region to virtual address */ if (dest->flags & REG_WRITE) map_type = PG_WRITE; else map_type = PG_READ; if (mmu_map(new_map->pgd, dest->phys, dest->addr, dest->size, map_type)) return NULL; } src = src->next; } while (src != &org_map->head); /* * No error. Now, link all shared regions */ dest = &new_map->head; src = &org_map->head; do { if (dest->flags & REG_SHARED) { src->flags |= REG_SHARED; dest->sh_prev = src; dest->sh_next = src->sh_next; src->sh_next->sh_prev = dest; src->sh_next = dest; } dest = dest->next; src = src->next; } while (src != &org_map->head); return new_map; }
static void vm_create_handler(RPC* rpc, VMSpec* vm_spec, void* context, void(*callback)(RPC* rpc, uint32_t id)) { uint32_t id = vm_create(vm_spec); callback(rpc, id); }
int main(int argc, char *argv[]) { char *vmname; int error, ch, vcpu, ptenum; vm_paddr_t gpa, gpa_pmap; size_t len; struct vm_exit vmexit; uint64_t ctl, eptp, bm, addr, u64, pteval[4], *pte; struct vmctx *ctx; int wired; cpuset_t cpus; uint64_t cr0, cr3, cr4, dr7, rsp, rip, rflags, efer, pat; uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp; uint64_t r8, r9, r10, r11, r12, r13, r14, r15; uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; struct option opts[] = { { "vm", REQ_ARG, 0, VMNAME }, { "cpu", REQ_ARG, 0, VCPU }, { "set-mem", REQ_ARG, 0, SET_MEM }, { "set-efer", REQ_ARG, 0, SET_EFER }, { "set-cr0", REQ_ARG, 0, SET_CR0 }, { "set-cr3", REQ_ARG, 0, SET_CR3 }, { "set-cr4", REQ_ARG, 0, SET_CR4 }, { "set-dr7", REQ_ARG, 0, SET_DR7 }, { "set-rsp", REQ_ARG, 0, SET_RSP }, { "set-rip", REQ_ARG, 0, SET_RIP }, { "set-rax", REQ_ARG, 0, SET_RAX }, { "set-rflags", REQ_ARG, 0, SET_RFLAGS }, { "desc-base", REQ_ARG, 0, DESC_BASE }, { "desc-limit", REQ_ARG, 0, DESC_LIMIT }, { "desc-access",REQ_ARG, 0, DESC_ACCESS }, { "set-cs", REQ_ARG, 0, SET_CS }, { "set-ds", REQ_ARG, 0, SET_DS }, { "set-es", REQ_ARG, 0, SET_ES }, { "set-fs", REQ_ARG, 0, SET_FS }, { "set-gs", REQ_ARG, 0, SET_GS }, { "set-ss", REQ_ARG, 0, SET_SS }, { "set-tr", REQ_ARG, 0, SET_TR }, { "set-ldtr", REQ_ARG, 0, SET_LDTR }, { "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE }, { "set-vmcs-exception-bitmap", REQ_ARG, 0, SET_VMCS_EXCEPTION_BITMAP }, { "set-vmcs-entry-interruption-info", REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO }, { "capname", REQ_ARG, 0, CAPNAME }, { "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV }, { "setcap", REQ_ARG, 0, SET_CAP }, { "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP }, { "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT }, { "getcap", NO_ARG, &getcap, 1 }, { "get-stats", NO_ARG, &get_stats, 1 }, { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, { "set-desc-ds",NO_ARG, &set_desc_ds, 1 }, { "get-desc-es",NO_ARG, &get_desc_es, 1 }, { "set-desc-es",NO_ARG, &set_desc_es, 1 }, { "get-desc-ss",NO_ARG, &get_desc_ss, 1 }, { "set-desc-ss",NO_ARG, &set_desc_ss, 1 }, { "get-desc-cs",NO_ARG, &get_desc_cs, 1 }, { "set-desc-cs",NO_ARG, &set_desc_cs, 1 }, { "get-desc-fs",NO_ARG, &get_desc_fs, 1 }, { "set-desc-fs",NO_ARG, &set_desc_fs, 1 }, { "get-desc-gs",NO_ARG, &get_desc_gs, 1 }, { "set-desc-gs",NO_ARG, &set_desc_gs, 1 }, { "get-desc-tr",NO_ARG, &get_desc_tr, 1 }, { "set-desc-tr",NO_ARG, &set_desc_tr, 1 }, { "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 }, { "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 }, { "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 }, { "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 }, { "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 }, { "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 }, { "get-lowmem", NO_ARG, &get_lowmem, 1 }, { "get-highmem",NO_ARG, &get_highmem, 1 }, { "get-efer", NO_ARG, &get_efer, 1 }, { "get-cr0", NO_ARG, &get_cr0, 1 }, { "get-cr3", NO_ARG, &get_cr3, 1 }, { "get-cr4", NO_ARG, &get_cr4, 1 }, { "get-dr7", NO_ARG, &get_dr7, 1 }, { "get-rsp", NO_ARG, &get_rsp, 1 }, { "get-rip", NO_ARG, &get_rip, 1 }, { "get-rax", NO_ARG, &get_rax, 1 }, { "get-rbx", NO_ARG, &get_rbx, 1 }, { "get-rcx", NO_ARG, &get_rcx, 1 }, { "get-rdx", NO_ARG, &get_rdx, 1 }, { "get-rsi", NO_ARG, &get_rsi, 1 }, { "get-rdi", NO_ARG, &get_rdi, 1 }, { "get-rbp", NO_ARG, &get_rbp, 1 }, { "get-r8", NO_ARG, &get_r8, 1 }, { "get-r9", NO_ARG, &get_r9, 1 }, { "get-r10", NO_ARG, &get_r10, 1 }, { "get-r11", NO_ARG, &get_r11, 1 }, { "get-r12", NO_ARG, &get_r12, 1 }, { "get-r13", NO_ARG, &get_r13, 1 }, { "get-r14", NO_ARG, &get_r14, 1 }, { "get-r15", NO_ARG, &get_r15, 1 }, { "get-rflags", NO_ARG, &get_rflags, 1 }, { "get-cs", NO_ARG, &get_cs, 1 }, { "get-ds", NO_ARG, &get_ds, 1 }, { "get-es", NO_ARG, &get_es, 1 }, { "get-fs", NO_ARG, &get_fs, 1 }, { "get-gs", NO_ARG, &get_gs, 1 }, { "get-ss", NO_ARG, &get_ss, 1 }, { "get-tr", NO_ARG, &get_tr, 1 }, { "get-ldtr", NO_ARG, &get_ldtr, 1 }, { "get-vmcs-pinbased-ctls", NO_ARG, &get_pinbased_ctls, 1 }, { "get-vmcs-procbased-ctls", NO_ARG, &get_procbased_ctls, 1 }, { "get-vmcs-procbased-ctls2", NO_ARG, &get_procbased_ctls2, 1 }, { "get-vmcs-guest-linear-address", NO_ARG, &get_vmcs_gla, 1 }, { "get-vmcs-guest-physical-address", NO_ARG, &get_vmcs_gpa, 1 }, { "get-vmcs-entry-interruption-info", NO_ARG, &get_vmcs_entry_interruption_info, 1}, { "get-vmcs-eptp", NO_ARG, &get_eptp, 1 }, { "get-vmcs-exception-bitmap", NO_ARG, &get_exception_bitmap, 1 }, { "get-vmcs-io-bitmap-address", NO_ARG, &get_io_bitmap, 1 }, { "get-vmcs-tsc-offset", NO_ARG,&get_tsc_offset, 1 }, { "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 }, { "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 }, { "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 }, { "get-vmcs-cr4-shadow", NO_ARG,&get_cr4_shadow, 1 }, { "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1}, { "get-vmcs-apic-access-address", NO_ARG, &get_apic_access_addr, 1}, { "get-vmcs-virtual-apic-address", NO_ARG, &get_virtual_apic_addr, 1}, { "get-vmcs-tpr-threshold", NO_ARG, &get_tpr_threshold, 1 }, { "get-vmcs-msr-bitmap", NO_ARG, &get_msr_bitmap, 1 }, { "get-vmcs-msr-bitmap-address", NO_ARG, &get_msr_bitmap_address, 1 }, { "get-vmcs-vpid", NO_ARG, &get_vpid, 1 }, { "get-vmcs-ple-gap", NO_ARG, &get_ple_gap, 1 }, { "get-vmcs-ple-window", NO_ARG,&get_ple_window,1 }, { "get-vmcs-instruction-error", NO_ARG, &get_inst_err, 1 }, { "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 }, { "get-vmcs-entry-ctls", NO_ARG, &get_entry_ctls, 1 }, { "get-vmcs-guest-pat", NO_ARG, &get_guest_pat, 1 }, { "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 }, { "get-vmcs-host-cr0", NO_ARG, &get_host_cr0, 1 }, { "get-vmcs-host-cr3", NO_ARG, &get_host_cr3, 1 }, { "get-vmcs-host-cr4", NO_ARG, &get_host_cr4, 1 }, { "get-vmcs-host-rip", NO_ARG, &get_host_rip, 1 }, { "get-vmcs-host-rsp", NO_ARG, &get_host_rsp, 1 }, { "get-vmcs-guest-sysenter", NO_ARG, &get_guest_sysenter, 1 }, { "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 }, { "get-vmcs-exit-reason", NO_ARG, &get_vmcs_exit_reason, 1 }, { "get-vmcs-exit-qualification", NO_ARG, &get_vmcs_exit_qualification, 1 }, { "get-vmcs-exit-interruption-info", NO_ARG, &get_vmcs_exit_interruption_info, 1}, { "get-vmcs-exit-interruption-error", NO_ARG, &get_vmcs_exit_interruption_error, 1}, { "get-vmcs-interruptibility", NO_ARG, &get_vmcs_interruptibility, 1 }, { "get-x2apic-state",NO_ARG, &get_x2apic_state, 1 }, { "get-all", NO_ARG, &get_all, 1 }, { "run", NO_ARG, &run, 1 }, { "create", NO_ARG, &create, 1 }, { "destroy", NO_ARG, &destroy, 1 }, { "inject-nmi", NO_ARG, &inject_nmi, 1 }, { "force-reset", NO_ARG, &force_reset, 1 }, { "force-poweroff", NO_ARG, &force_poweroff, 1 }, { "get-active-cpus", NO_ARG, &get_active_cpus, 1 }, { "get-suspended-cpus", NO_ARG, &get_suspended_cpus, 1 }, { NULL, 0, NULL, 0 } }; vcpu = 0; vmname = NULL; assert_lapic_lvt = -1; progname = basename(argv[0]); while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) { switch (ch) { case 0: break; case VMNAME: vmname = optarg; break; case VCPU: vcpu = atoi(optarg); break; case SET_MEM: memsize = atoi(optarg) * MB; memsize = roundup(memsize, 2 * MB); break; case SET_EFER: efer = strtoul(optarg, NULL, 0); set_efer = 1; break; case SET_CR0: cr0 = strtoul(optarg, NULL, 0); set_cr0 = 1; break; case SET_CR3: cr3 = strtoul(optarg, NULL, 0); set_cr3 = 1; break; case SET_CR4: cr4 = strtoul(optarg, NULL, 0); set_cr4 = 1; break; case SET_DR7: dr7 = strtoul(optarg, NULL, 0); set_dr7 = 1; break; case SET_RSP: rsp = strtoul(optarg, NULL, 0); set_rsp = 1; break; case SET_RIP: rip = strtoul(optarg, NULL, 0); set_rip = 1; break; case SET_RAX: rax = strtoul(optarg, NULL, 0); set_rax = 1; break; case SET_RFLAGS: rflags = strtoul(optarg, NULL, 0); set_rflags = 1; break; case DESC_BASE: desc_base = strtoul(optarg, NULL, 0); break; case DESC_LIMIT: desc_limit = strtoul(optarg, NULL, 0); break; case DESC_ACCESS: desc_access = strtoul(optarg, NULL, 0); break; case SET_CS: cs = strtoul(optarg, NULL, 0); set_cs = 1; break; case SET_DS: ds = strtoul(optarg, NULL, 0); set_ds = 1; break; case SET_ES: es = strtoul(optarg, NULL, 0); set_es = 1; break; case SET_FS: fs = strtoul(optarg, NULL, 0); set_fs = 1; break; case SET_GS: gs = strtoul(optarg, NULL, 0); set_gs = 1; break; case SET_SS: ss = strtoul(optarg, NULL, 0); set_ss = 1; break; case SET_TR: tr = strtoul(optarg, NULL, 0); set_tr = 1; break; case SET_LDTR: ldtr = strtoul(optarg, NULL, 0); set_ldtr = 1; break; case SET_X2APIC_STATE: x2apic_state = strtol(optarg, NULL, 0); set_x2apic_state = 1; break; case SET_VMCS_EXCEPTION_BITMAP: exception_bitmap = strtoul(optarg, NULL, 0); set_exception_bitmap = 1; break; case SET_VMCS_ENTRY_INTERRUPTION_INFO: vmcs_entry_interruption_info = strtoul(optarg, NULL, 0); set_vmcs_entry_interruption_info = 1; break; case SET_CAP: capval = strtoul(optarg, NULL, 0); setcap = 1; break; case GET_GPA_PMAP: gpa_pmap = strtoul(optarg, NULL, 0); get_gpa_pmap = 1; break; case CAPNAME: capname = optarg; break; case UNASSIGN_PPTDEV: unassign_pptdev = 1; if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3) usage(); break; case ASSERT_LAPIC_LVT: assert_lapic_lvt = atoi(optarg); break; default: usage(); } } argc -= optind; argv += optind; if (vmname == NULL) usage(); error = 0; if (!error && create) error = vm_create(vmname); if (!error) { ctx = vm_open(vmname); if (ctx == NULL) error = -1; } if (!error && memsize) error = vm_setup_memory(ctx, memsize, VM_MMAP_NONE); if (!error && set_efer) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer); if (!error && set_cr0) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0); if (!error && set_cr3) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3); if (!error && set_cr4) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4); if (!error && set_dr7) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7); if (!error && set_rsp) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp); if (!error && set_rip) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip); if (!error && set_rax) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax); if (!error && set_rflags) { error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); } if (!error && set_desc_ds) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS, desc_base, desc_limit, desc_access); } if (!error && set_desc_es) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES, desc_base, desc_limit, desc_access); } if (!error && set_desc_ss) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS, desc_base, desc_limit, desc_access); } if (!error && set_desc_cs) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS, desc_base, desc_limit, desc_access); } if (!error && set_desc_fs) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS, desc_base, desc_limit, desc_access); } if (!error && set_desc_gs) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS, desc_base, desc_limit, desc_access); } if (!error && set_desc_tr) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR, desc_base, desc_limit, desc_access); } if (!error && set_desc_ldtr) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR, desc_base, desc_limit, desc_access); } if (!error && set_desc_gdtr) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR, desc_base, desc_limit, 0); } if (!error && set_desc_idtr) { error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR, desc_base, desc_limit, 0); } if (!error && set_cs) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs); if (!error && set_ds) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds); if (!error && set_es) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es); if (!error && set_fs) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs); if (!error && set_gs) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs); if (!error && set_ss) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss); if (!error && set_tr) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr); if (!error && set_ldtr) error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr); if (!error && set_x2apic_state) error = vm_set_x2apic_state(ctx, vcpu, x2apic_state); if (!error && unassign_pptdev) error = vm_unassign_pptdev(ctx, bus, slot, func); if (!error && set_exception_bitmap) { error = vm_set_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, exception_bitmap); } if (!error && set_vmcs_entry_interruption_info) { error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO, vmcs_entry_interruption_info); } if (!error && inject_nmi) { error = vm_inject_nmi(ctx, vcpu); } if (!error && assert_lapic_lvt != -1) { error = vm_lapic_local_irq(ctx, vcpu, assert_lapic_lvt); } if (!error && (get_lowmem || get_all)) { gpa = 0; error = vm_get_memory_seg(ctx, gpa, &len, &wired); if (error == 0) printf("lowmem\t\t0x%016lx/%ld%s\n", gpa, len, wired ? " wired" : ""); } if (!error && (get_highmem || get_all)) { gpa = 4 * GB; error = vm_get_memory_seg(ctx, gpa, &len, &wired); if (error == 0) printf("highmem\t\t0x%016lx/%ld%s\n", gpa, len, wired ? " wired" : ""); } if (!error && (get_efer || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer); if (error == 0) printf("efer[%d]\t\t0x%016lx\n", vcpu, efer); } if (!error && (get_cr0 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0); if (error == 0) printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0); } if (!error && (get_cr3 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3); if (error == 0) printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3); } if (!error && (get_cr4 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4); if (error == 0) printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4); } if (!error && (get_dr7 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7); if (error == 0) printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7); } if (!error && (get_rsp || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp); if (error == 0) printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp); } if (!error && (get_rip || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); if (error == 0) printf("rip[%d]\t\t0x%016lx\n", vcpu, rip); } if (!error && (get_rax || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax); if (error == 0) printf("rax[%d]\t\t0x%016lx\n", vcpu, rax); } if (!error && (get_rbx || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx); if (error == 0) printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx); } if (!error && (get_rcx || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx); if (error == 0) printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx); } if (!error && (get_rdx || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx); if (error == 0) printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx); } if (!error && (get_rsi || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi); if (error == 0) printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi); } if (!error && (get_rdi || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi); if (error == 0) printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi); } if (!error && (get_rbp || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp); if (error == 0) printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp); } if (!error && (get_r8 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8); if (error == 0) printf("r8[%d]\t\t0x%016lx\n", vcpu, r8); } if (!error && (get_r9 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9); if (error == 0) printf("r9[%d]\t\t0x%016lx\n", vcpu, r9); } if (!error && (get_r10 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10); if (error == 0) printf("r10[%d]\t\t0x%016lx\n", vcpu, r10); } if (!error && (get_r11 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11); if (error == 0) printf("r11[%d]\t\t0x%016lx\n", vcpu, r11); } if (!error && (get_r12 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12); if (error == 0) printf("r12[%d]\t\t0x%016lx\n", vcpu, r12); } if (!error && (get_r13 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13); if (error == 0) printf("r13[%d]\t\t0x%016lx\n", vcpu, r13); } if (!error && (get_r14 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14); if (error == 0) printf("r14[%d]\t\t0x%016lx\n", vcpu, r14); } if (!error && (get_r15 || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15); if (error == 0) printf("r15[%d]\t\t0x%016lx\n", vcpu, r15); } if (!error && (get_rflags || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, &rflags); if (error == 0) printf("rflags[%d]\t0x%016lx\n", vcpu, rflags); } if (!error && (get_stats || get_all)) { int i, num_stats; uint64_t *stats; struct timeval tv; const char *desc; stats = vm_get_stats(ctx, vcpu, &tv, &num_stats); if (stats != NULL) { printf("vcpu%d\n", vcpu); for (i = 0; i < num_stats; i++) { desc = vm_get_stat_desc(ctx, i); printf("%-40s\t%ld\n", desc, stats[i]); } } } if (!error && (get_desc_ds || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_es || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_fs || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_gs || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_ss || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_cs || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_tr || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_ldtr || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", vcpu, desc_base, desc_limit, desc_access); } } if (!error && (get_desc_gdtr || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("gdtr[%d]\t\t0x%016lx/0x%08x\n", vcpu, desc_base, desc_limit); } } if (!error && (get_desc_idtr || get_all)) { error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR, &desc_base, &desc_limit, &desc_access); if (error == 0) { printf("idtr[%d]\t\t0x%016lx/0x%08x\n", vcpu, desc_base, desc_limit); } } if (!error && (get_cs || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs); if (error == 0) printf("cs[%d]\t\t0x%04lx\n", vcpu, cs); } if (!error && (get_ds || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds); if (error == 0) printf("ds[%d]\t\t0x%04lx\n", vcpu, ds); } if (!error && (get_es || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es); if (error == 0) printf("es[%d]\t\t0x%04lx\n", vcpu, es); } if (!error && (get_fs || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs); if (error == 0) printf("fs[%d]\t\t0x%04lx\n", vcpu, fs); } if (!error && (get_gs || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs); if (error == 0) printf("gs[%d]\t\t0x%04lx\n", vcpu, gs); } if (!error && (get_ss || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss); if (error == 0) printf("ss[%d]\t\t0x%04lx\n", vcpu, ss); } if (!error && (get_tr || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr); if (error == 0) printf("tr[%d]\t\t0x%04lx\n", vcpu, tr); } if (!error && (get_ldtr || get_all)) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr); if (error == 0) printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr); } if (!error && (get_x2apic_state || get_all)) { error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state); if (error == 0) printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state); } if (!error && (get_pinbased_ctls || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl); if (error == 0) printf("pinbased_ctls[%d]\t0x%08lx\n", vcpu, ctl); } if (!error && (get_procbased_ctls || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_PRI_PROC_BASED_CTLS, &ctl); if (error == 0) printf("procbased_ctls[%d]\t0x%08lx\n", vcpu, ctl); } if (!error && (get_procbased_ctls2 || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_SEC_PROC_BASED_CTLS, &ctl); if (error == 0) printf("procbased_ctls2[%d]\t0x%08lx\n", vcpu, ctl); } if (!error && (get_vmcs_gla || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_LINEAR_ADDRESS, &u64); if (error == 0) printf("gla[%d]\t\t0x%016lx\n", vcpu, u64); } if (!error && (get_vmcs_gpa || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_PHYSICAL_ADDRESS, &u64); if (error == 0) printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64); } if (!error && (get_vmcs_entry_interruption_info || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64); if (error == 0) { printf("entry_interruption_info[%d]\t0x%08lx\n", vcpu, u64); } } if (!error && (get_eptp || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp); if (error == 0) printf("eptp[%d]\t\t0x%016lx\n", vcpu, eptp); } if (!error && (get_exception_bitmap || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXCEPTION_BITMAP, &bm); if (error == 0) printf("exception_bitmap[%d]\t0x%08lx\n", vcpu, bm); } if (!error && (get_io_bitmap || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A, &bm); if (error == 0) printf("io_bitmap_a[%d]\t0x%08lx\n", vcpu, bm); error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B, &bm); if (error == 0) printf("io_bitmap_b[%d]\t0x%08lx\n", vcpu, bm); } if (!error && (get_tsc_offset || get_all)) { uint64_t tscoff; error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET, &tscoff); if (error == 0) printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff); } if (!error && (get_cr0_mask || get_all)) { uint64_t cr0mask; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask); if (error == 0) printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask); } if (!error && (get_cr0_shadow || get_all)) { uint64_t cr0shadow; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW, &cr0shadow); if (error == 0) printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow); } if (!error && (get_cr4_mask || get_all)) { uint64_t cr4mask; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask); if (error == 0) printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask); } if (!error && (get_cr4_shadow || get_all)) { uint64_t cr4shadow; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW, &cr4shadow); if (error == 0) printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow); } if (!error && (get_cr3_targets || get_all)) { uint64_t target_count, target_addr; error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT, &target_count); if (error == 0) { printf("cr3_target_count[%d]\t0x%08lx\n", vcpu, target_count); } error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0, &target_addr); if (error == 0) { printf("cr3_target0[%d]\t\t0x%016lx\n", vcpu, target_addr); } error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1, &target_addr); if (error == 0) { printf("cr3_target1[%d]\t\t0x%016lx\n", vcpu, target_addr); } error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2, &target_addr); if (error == 0) { printf("cr3_target2[%d]\t\t0x%016lx\n", vcpu, target_addr); } error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3, &target_addr); if (error == 0) { printf("cr3_target3[%d]\t\t0x%016lx\n", vcpu, target_addr); } } if (!error && (get_apic_access_addr || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_APIC_ACCESS, &addr); if (error == 0) printf("apic_access_addr[%d]\t0x%016lx\n", vcpu, addr); } if (!error && (get_virtual_apic_addr || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_VIRTUAL_APIC, &addr); if (error == 0) printf("virtual_apic_addr[%d]\t0x%016lx\n", vcpu, addr); } if (!error && (get_tpr_threshold || get_all)) { uint64_t threshold; error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD, &threshold); if (error == 0) printf("tpr_threshold[%d]\t0x%08lx\n", vcpu, threshold); } if (!error && (get_msr_bitmap_address || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); if (error == 0) printf("msr_bitmap[%d]\t\t0x%016lx\n", vcpu, addr); } if (!error && (get_msr_bitmap || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, &addr); if (error == 0) error = dump_vmcs_msr_bitmap(vcpu, addr); } if (!error && (get_vpid || get_all)) { uint64_t vpid; error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid); if (error == 0) printf("vpid[%d]\t\t0x%04lx\n", vcpu, vpid); } if (!error && (get_ple_window || get_all)) { uint64_t window; error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_WINDOW, &window); if (error == 0) printf("ple_window[%d]\t\t0x%08lx\n", vcpu, window); } if (!error && (get_ple_gap || get_all)) { uint64_t gap; error = vm_get_vmcs_field(ctx, vcpu, VMCS_PLE_GAP, &gap); if (error == 0) printf("ple_gap[%d]\t\t0x%08lx\n", vcpu, gap); } if (!error && (get_inst_err || get_all)) { uint64_t insterr; error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR, &insterr); if (error == 0) { printf("instruction_error[%d]\t0x%08lx\n", vcpu, insterr); } } if (!error && (get_exit_ctls || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl); if (error == 0) printf("exit_ctls[%d]\t\t0x%08lx\n", vcpu, ctl); } if (!error && (get_entry_ctls || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl); if (error == 0) printf("entry_ctls[%d]\t\t0x%08lx\n", vcpu, ctl); } if (!error && (get_host_pat || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat); if (error == 0) printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat); } if (!error && (get_guest_pat || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_PAT, &pat); if (error == 0) printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat); } if (!error && (get_host_cr0 || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0); if (error == 0) printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0); } if (!error && (get_host_cr3 || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3); if (error == 0) printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3); } if (!error && (get_host_cr4 || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4); if (error == 0) printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4); } if (!error && (get_host_rip || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip); if (error == 0) printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip); } if (!error && (get_host_rsp || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp); if (error == 0) printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp); } if (!error && (get_guest_sysenter || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_SYSENTER_CS, &cs); if (error == 0) printf("guest_sysenter_cs[%d]\t0x%08lx\n", vcpu, cs); error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_SYSENTER_ESP, &rsp); if (error == 0) printf("guest_sysenter_sp[%d]\t0x%016lx\n", vcpu, rsp); error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_IA32_SYSENTER_EIP, &rip); if (error == 0) printf("guest_sysenter_ip[%d]\t0x%016lx\n", vcpu, rip); } if (!error && (get_vmcs_link || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr); if (error == 0) printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr); } if (!error && (get_vmcs_exit_reason || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON, &u64); if (error == 0) printf("vmcs_exit_reason[%d]\t0x%016lx\n", vcpu, u64); } if (!error && (get_vmcs_exit_qualification || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION, &u64); if (error == 0) printf("vmcs_exit_qualification[%d]\t0x%016lx\n", vcpu, u64); } if (!error && (get_vmcs_exit_interruption_info || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_INFO, &u64); if (error == 0) { printf("vmcs_exit_interruption_info[%d]\t0x%08lx\n", vcpu, u64); } } if (!error && (get_vmcs_exit_interruption_error || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_ERRCODE, &u64); if (error == 0) { printf("vmcs_exit_interruption_error[%d]\t0x%08lx\n", vcpu, u64); } } if (!error && (get_vmcs_interruptibility || get_all)) { error = vm_get_vmcs_field(ctx, vcpu, VMCS_GUEST_INTERRUPTIBILITY, &u64); if (error == 0) { printf("vmcs_guest_interruptibility[%d]\t0x%08lx\n", vcpu, u64); } } if (!error && setcap) { int captype; captype = vm_capability_name2type(capname); error = vm_set_capability(ctx, vcpu, captype, capval); if (error != 0 && errno == ENOENT) printf("Capability \"%s\" is not available\n", capname); } if (!error && get_gpa_pmap) { error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum); if (error == 0) { printf("gpa %#lx:", gpa_pmap); pte = &pteval[0]; while (ptenum-- > 0) printf(" %#lx", *pte++); printf("\n"); } } if (!error && (getcap || get_all)) { int captype, val, getcaptype; if (getcap && capname) getcaptype = vm_capability_name2type(capname); else getcaptype = -1; for (captype = 0; captype < VM_CAP_MAX; captype++) { if (getcaptype >= 0 && captype != getcaptype) continue; error = vm_get_capability(ctx, vcpu, captype, &val); if (error == 0) { printf("Capability \"%s\" is %s on vcpu %d\n", vm_capability_type2name(captype), val ? "set" : "not set", vcpu); } else if (errno == ENOENT) { error = 0; printf("Capability \"%s\" is not available\n", vm_capability_type2name(captype)); } else { break; } } } if (!error && (get_active_cpus || get_all)) { error = vm_active_cpus(ctx, &cpus); if (!error) print_cpus("active cpus", &cpus); } if (!error && (get_suspended_cpus || get_all)) { error = vm_suspended_cpus(ctx, &cpus); if (!error) print_cpus("suspended cpus", &cpus); } if (!error && run) { error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); assert(error == 0); error = vm_run(ctx, vcpu, rip, &vmexit); if (error == 0) dump_vm_run_exitcode(&vmexit, vcpu); else printf("vm_run error %d\n", error); } if (!error && force_reset) error = vm_suspend(ctx, VM_SUSPEND_RESET); if (!error && force_poweroff) error = vm_suspend(ctx, VM_SUSPEND_POWEROFF); if (error) printf("errno = %d\n", errno); if (!error && destroy) vm_destroy(ctx); exit(error); }
static struct vmctx * do_open(const char *vmname) { struct vmctx *ctx; int error; bool reinit, romboot; #ifndef WITHOUT_CAPSICUM cap_rights_t rights; const cap_ioctl_t *cmds; size_t ncmds; #endif reinit = romboot = false; if (lpc_bootrom()) romboot = true; error = vm_create(vmname); if (error) { if (errno == EEXIST) { if (romboot) { reinit = true; } else { /* * The virtual machine has been setup by the * userspace bootloader. */ } } else { perror("vm_create"); exit(1); } } else { if (!romboot) { /* * If the virtual machine was just created then a * bootrom must be configured to boot it. */ fprintf(stderr, "virtual machine cannot be booted\n"); exit(1); } } ctx = vm_open(vmname); if (ctx == NULL) { perror("vm_open"); exit(1); } #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RW); if (cap_rights_limit(vm_get_device_fd(ctx), &rights) == -1 && errno != ENOSYS) errx(EX_OSERR, "Unable to apply rights for sandbox"); vm_get_ioctls(&ncmds); cmds = vm_get_ioctls(NULL); if (cmds == NULL) errx(EX_OSERR, "out of memory"); if (cap_ioctls_limit(vm_get_device_fd(ctx), cmds, ncmds) == -1 && errno != ENOSYS) errx(EX_OSERR, "Unable to apply rights for sandbox"); free((cap_ioctl_t *)cmds); #endif if (reinit) { error = vm_reinit(ctx); if (error) { perror("vm_reinit"); exit(1); } } error = vm_set_topology(ctx, sockets, cores, threads, maxcpus); if (error) errx(EX_OSERR, "vm_set_topology"); return (ctx); }