Ejemplo n.º 1
0
/* Map a device at the specified physical address */
int vm_map_device(vm_instance_t *vm,struct vdevice *dev,m_uint64_t base_addr)
{
#if 0   
   /* Suspend VM activity */
   vm_suspend(vm);

   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      fprintf(stderr,"VM%u: unable to sync with system CPUs.\n",
              vm->instance_id);
      return(-1);
   }
#endif

   /* Unbind the device if it was already active */
   vm_unbind_device(vm,dev);

   /* Map the device at the new base address and rebuild MTS */
   dev->phys_addr = base_addr;
   vm_bind_device(vm,dev);
   cpu_group_rebuild_mts(vm->cpu_group);

#if 0
   vm_resume(vm);
#endif
   return(0);
}
Ejemplo n.º 2
0
/* Boot the ELF image */
static int ppc32_vmtest_boot_elf(vm_instance_t *vm)
{     
   m_uint32_t rom_entry_point;
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Load ROM (ELF image or embedded) */
   cpu = CPU_PPC32(vm->boot_cpu);
   rom_entry_point = (m_uint32_t)PPC32_ROM_START;

   if ((vm->rom_filename != NULL) &&
       (ppc32_load_elf_image(cpu,vm->rom_filename,0,&rom_entry_point) < 0))
   {
      vm_error(vm,"unable to load alternate ROM '%s', "
               "fallback to embedded ROM.\n\n",vm->rom_filename);
      vm->rom_filename = NULL;
   }

   /* Load ELF image */
   if (ppc32_load_elf_image(cpu,vm->ios_image,
                            (vm->ghost_status == VM_GHOST_RAM_USE),
                            &vm->ios_entry_point) < 0)
   {
      vm_error(vm,"failed to load ELF image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nPPC32_VMTEST '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"PPC32_VMTEST_BOOT",
          "starting instance (CPU0 IA=0x%8.8x,JIT %s)\n",
          cpu->ia,vm->jit_use ? "on":"off");
   
   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
Ejemplo n.º 3
0
/* Boot the IOS image */
static int c1700_boot_ios(c1700_t *router)
{   
   vm_instance_t *vm = router->vm;
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Adjust stack pointer */
   cpu->gpr[1] |= 0x80000000;

   /* Load BAT registers */
   printf("Loading BAT registers\n");
   ppc32_load_bat_array(cpu,bat_array);
   cpu->msr |= PPC32_MSR_IR|PPC32_MSR_DR;

   /* IRQ routing */
   vm->set_irq = c1700_set_irq;
   vm->clear_irq = c1700_clear_irq;

   /* Load IOS image */
   if (ppc32_load_elf_image(cpu,vm->ios_image,
                            (vm->ghost_status == VM_GHOST_RAM_USE),
                            &vm->ios_entry_point) < 0) 
   {
      vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nC1700 '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"C1700_BOOT",
          "starting instance (CPU0 PC=0x%8.8x,idle_pc=0x%8.8x,JIT %s)\n",
          cpu->ia,cpu->idle_pc,vm->jit_use ? "on":"off");

   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
Ejemplo n.º 4
0
/* Suspend a VM instance */
static int cmd_suspend(hypervisor_conn_t *conn,int argc,char *argv[])
{
   vm_instance_t *vm;

   if (!(vm = hypervisor_find_object(conn,argv[0],OBJ_TYPE_VM)))
      return(-1);

   vm_suspend(vm);

   vm_release(vm);
   hypervisor_send_reply(conn,HSC_INFO_OK,1,"VM '%s' suspended",argv[0]);
   return(0);
}
Ejemplo n.º 5
0
/* Boot the IOS image */
static int c3725_boot_ios(c3725_t *router)
{   
   vm_instance_t *vm = router->vm;
   cpu_mips_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_MIPS64(vm->boot_cpu);
   mips64_reset(cpu);

   /* Load IOS image */
   if (mips64_load_elf_image(cpu,vm->ios_image,
                             (vm->ghost_status == VM_GHOST_RAM_USE),
                             &vm->ios_entry_point) < 0) 
   {
      vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nC3725 '%s': starting simulation (CPU0 PC=0x%llx), "
          "JIT %sabled.\n",
          vm->name,cpu->pc,vm->jit_use ? "en":"dis");

   vm_log(vm,"C3725_BOOT",
          "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n",
          cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");

   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
Ejemplo n.º 6
0
static int adm5120_boot (adm5120_t * adm5120)
{
    vm_instance_t *vm = adm5120->vm;
    cpu_mips_t *cpu;
    m_va_t kernel_entry_point;

    if (!vm->boot_cpu)
        return (-1);

    vm_suspend (vm);

    /* Check that CPU activity is really suspended */
    if (cpu_group_sync_state (vm->cpu_group) == -1) {
        vm_error (vm, "unable to sync with system CPUs.\n");
        return (-1);
    }

    /* Reset the boot CPU */
    cpu = (vm->boot_cpu);
    mips_reset (cpu);

    /*set configure register */
    cpu->cp0.config_usable = 0x3;       /*only configure sel 0 and 1 is valid */
    cpu->cp0.config_reg[0] = ADM5120_CONFIG0;
    cpu->cp0.config_reg[1] = ADM5120_CONFIG1;

    /*set PC and PRID */
    cpu->cp0.reg[MIPS_CP0_PRID] = ADM5120_PRID;
    cpu->cp0.tlb_entries = ADM5120_DEFAULT_TLB_ENTRYNO;
    cpu->pc = ADM5120_ROM_PC;
    /*If we boot from elf kernel image, load the image and set pc to elf entry */
    if (vm->boot_method == BOOT_ELF) {
        if (mips_load_elf_image (cpu, vm->kernel_filename,
                &kernel_entry_point) == -1)
            return (-1);
        adm5120_reg_default_value (adm5120);
        cpu->pc = kernel_entry_point;
    }

    /* Launch the simulation */
    printf ("\nADM5120 '%s': starting simulation (CPU0 PC=0x%" LL "x), "
        "JIT %sabled.\n", vm->name, cpu->pc, vm->jit_use ? "en" : "dis");

    vm->status = VM_STATUS_RUNNING;
    cpu_start (vm->boot_cpu);
    return (0);

}
Ejemplo n.º 7
0
/* Boot the RAW image */
_unused static int ppc32_vmtest_boot_raw(vm_instance_t *vm)
{   
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Load RAW image */
   if (ppc32_load_raw_image(cpu,vm->ios_image,0xFFF00000) < 0) {
      vm_error(vm,"failed to load RAW image '%s'.\n",vm->ios_image);
      return(-1);
   }

   cpu->ia = 0xFFF00100;
   cpu->gpr[1] = 0x2000;

   /* Launch the simulation */
   printf("\nPPC32_VMTEST '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"PPC32_VMTEST_BOOT",
          "starting instance (CPU0 IA=0x%8.8x,JIT %s)\n",
          cpu->ia,vm->jit_use ? "on":"off");
   
   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
Ejemplo n.º 8
0
Archivo: vmm.c Proyecto: RnbWd/hyperkit
static int
nested_fault(struct vm *vm, int vcpuid, uint64_t info1, uint64_t info2,
    uint64_t *retinfo)
{
	enum exc_class exc1, exc2;
	int type1, vector1;

	KASSERT(info1 & VM_INTINFO_VALID, ("info1 %#llx is not valid", info1));
	KASSERT(info2 & VM_INTINFO_VALID, ("info2 %#llx is not valid", info2));

	/*
	 * If an exception occurs while attempting to call the double-fault
	 * handler the processor enters shutdown mode (aka triple fault).
	 */
	type1 = info1 & VM_INTINFO_TYPE;
	vector1 = info1 & 0xff;
	if (type1 == VM_INTINFO_HWEXCEPTION && vector1 == IDT_DF) {
		VCPU_CTR2(vm, vcpuid, "triple fault: info1(%#llx), info2(%#llx)",
		    info1, info2);
		vm_suspend(vm, VM_SUSPEND_TRIPLEFAULT);
		*retinfo = 0;
		return (0);
	}

	/*
	 * Table 6-5 "Conditions for Generating a Double Fault", Intel SDM, Vol3
	 */
	exc1 = exception_class(info1);
	exc2 = exception_class(info2);
	if ((exc1 == EXC_CONTRIBUTORY && exc2 == EXC_CONTRIBUTORY) ||
	    (exc1 == EXC_PAGEFAULT && exc2 != EXC_BENIGN)) {
		/* Convert nested fault into a double fault. */
		*retinfo = IDT_DF;
		*retinfo |= VM_INTINFO_VALID | VM_INTINFO_HWEXCEPTION;
		*retinfo |= VM_INTINFO_DEL_ERRCODE;
	} else {
		/* Handle exceptions serially */
		*retinfo = info2;
	}
	return (1);
}
Ejemplo n.º 9
0
static int
atkbdc_sts_ctl_handler(struct vmctx *ctx, int vcpu, int in, int port,
    int bytes, uint32_t *eax, void *arg)
{
	int error, retval;

	if (bytes != 1)
		return (-1);

	retval = 0;
	if (in) {
		*eax = KBD_SYS_FLAG;	/* system passed POST */
	} else {
		switch (*eax) {
		case KBDC_RESET:	/* Pulse "reset" line. */
			error = vm_suspend(ctx, VM_SUSPEND_RESET);
			assert(error == 0 || errno == EALREADY);
			break;
		}
	}

	return (retval);
}
Ejemplo n.º 10
0
Archivo: vmm.c Proyecto: RnbWd/hyperkit
/*
 * Emulate a guest 'hlt' by sleeping until the vcpu is ready to run.
 */
static int
vm_handle_hlt(struct vm *vm, int vcpuid, bool intr_disabled)
{
	struct vcpu *vcpu;
	const char *wmesg;
	int vcpu_halted, vm_halted;
	const struct timespec ts = {.tv_sec = 1, .tv_nsec = 0}; /* 1 second */

	KASSERT(!CPU_ISSET(((unsigned) vcpuid), &vm->halted_cpus),
		("vcpu already halted"));

	vcpu = &vm->vcpu[vcpuid];
	vcpu_halted = 0;
	vm_halted = 0;

	vcpu_lock(vcpu);
	while (1) {
		/*
		 * Do a final check for pending NMI or interrupts before
		 * really putting this thread to sleep. Also check for
		 * software events that would cause this vcpu to wakeup.
		 *
		 * These interrupts/events could have happened after the
		 * vcpu returned from VMRUN() and before it acquired the
		 * vcpu lock above.
		 */
		if (vm->rendezvous_func != NULL || vm->suspend)
			break;
		if (vm_nmi_pending(vm, vcpuid))
			break;
		if (!intr_disabled) {
			if (vm_extint_pending(vm, vcpuid) ||
			    vlapic_pending_intr(vcpu->vlapic, NULL)) {
				break;
			}
		}

		/*
		 * Some Linux guests implement "halt" by having all vcpus
		 * execute HLT with interrupts disabled. 'halted_cpus' keeps
		 * track of the vcpus that have entered this state. When all
		 * vcpus enter the halted state the virtual machine is halted.
		 */
		if (intr_disabled) {
			wmesg = "vmhalt";
			VCPU_CTR0(vm, vcpuid, "Halted");
			if (!vcpu_halted && halt_detection_enabled) {
				vcpu_halted = 1;
				CPU_SET_ATOMIC(((unsigned) vcpuid), &vm->halted_cpus);
			}
			if (CPU_CMP(&vm->halted_cpus, &vm->active_cpus) == 0) {
				vm_halted = 1;
				break;
			}
		} else {
			wmesg = "vmidle";
		}

		//t = ticks;
		vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
		/*
		 * XXX msleep_spin() cannot be interrupted by signals so
		 * wake up periodically to check pending signals.
		 */
		pthread_mutex_lock(&vcpu->vcpu_sleep_mtx);
		vcpu_unlock(vcpu);
		pthread_cond_timedwait_relative_np(&vcpu->vcpu_sleep_cnd,
			&vcpu->vcpu_sleep_mtx, &ts);
		vcpu_lock(vcpu);
		pthread_mutex_unlock(&vcpu->vcpu_sleep_mtx);
		//msleep_spin(vcpu, &vcpu->mtx, wmesg, hz);
		vcpu_require_state_locked(vcpu, VCPU_FROZEN);
		//vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t);
	}

	if (vcpu_halted)
		CPU_CLR_ATOMIC(((unsigned) vcpuid), &vm->halted_cpus);

	vcpu_unlock(vcpu);

	if (vm_halted)
		vm_suspend(vm, VM_SUSPEND_HALT);

	return (0);
}

static int
vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
{
	struct vie *vie;
	struct vcpu *vcpu;
	struct vm_exit *vme;
	uint64_t gla, gpa, cs_base;
	struct vm_guest_paging *paging;
	mem_region_read_t mread;
	mem_region_write_t mwrite;
	enum vm_cpu_mode cpu_mode;
	int cs_d, error, fault, length;

	vcpu = &vm->vcpu[vcpuid];
	vme = &vcpu->exitinfo;

	gla = vme->u.inst_emul.gla;
	gpa = vme->u.inst_emul.gpa;
	cs_base = vme->u.inst_emul.cs_base;
	cs_d = vme->u.inst_emul.cs_d;
	vie = &vme->u.inst_emul.vie;
	paging = &vme->u.inst_emul.paging;
	cpu_mode = paging->cpu_mode;

	VCPU_CTR1(vm, vcpuid, "inst_emul fault accessing gpa %#llx", gpa);

	/* Fetch, decode and emulate the faulting instruction */
	if (vie->num_valid == 0) {
		/*
		 * If the instruction length is not known then assume a
		 * maximum size instruction.
		 */
		length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE;
		error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip +
		    cs_base, length, vie, &fault);
	} else {
		/*
		 * The instruction bytes have already been copied into 'vie'
		 */
		error = fault = 0;
	}
	if (error || fault)
		return (error);

	if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0) {
		VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#llx",
		    vme->rip + cs_base);
		*retu = true;	    /* dump instruction bytes in userspace */
		return (0);
	}

	/*
	 * If the instruction length was not specified then update it now
	 * along with 'nextrip'.
	 */
	if (vme->inst_length == 0) {
		vme->inst_length = vie->num_processed;
		vcpu->nextrip += vie->num_processed;
	}
 
	/* return to userland unless this is an in-kernel emulated device */
	if (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + XHYVE_PAGE_SIZE) {
		mread = lapic_mmio_read;
		mwrite = lapic_mmio_write;
	} else if (gpa >= VIOAPIC_BASE && gpa < VIOAPIC_BASE + VIOAPIC_SIZE) {
		mread = vioapic_mmio_read;
		mwrite = vioapic_mmio_write;
	} else if (gpa >= VHPET_BASE && gpa < VHPET_BASE + VHPET_SIZE) {
		mread = vhpet_mmio_read;
		mwrite = vhpet_mmio_write;
	} else {
		*retu = true;
		return (0);
	}

	error = vmm_emulate_instruction(vm, vcpuid, gpa, vie, paging,
	    mread, mwrite, retu);

	return (error);
}

static int
vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu)
{
	int i, done;
	struct vcpu *vcpu;
	const struct timespec ts = {.tv_sec = 1, .tv_nsec = 0}; /* 1 second */

	done = 0;
	vcpu = &vm->vcpu[vcpuid];

	CPU_SET_ATOMIC(((unsigned) vcpuid), &vm->suspended_cpus);

	/*
	 * Wait until all 'active_cpus' have suspended themselves.
	 *
	 * Since a VM may be suspended at any time including when one or
	 * more vcpus are doing a rendezvous we need to call the rendezvous
	 * handler while we are waiting to prevent a deadlock.
	 */
	vcpu_lock(vcpu);
	while (1) {
		if (CPU_CMP(&vm->suspended_cpus, &vm->active_cpus) == 0) {
			VCPU_CTR0(vm, vcpuid, "All vcpus suspended");
			break;
		}

		if (vm->rendezvous_func == NULL) {
			VCPU_CTR0(vm, vcpuid, "Sleeping during suspend");
			vcpu_require_state_locked(vcpu, VCPU_SLEEPING);

			pthread_mutex_lock(&vcpu->vcpu_sleep_mtx);
			vcpu_unlock(vcpu);
			pthread_cond_timedwait_relative_np(&vcpu->vcpu_sleep_cnd,
				&vcpu->vcpu_sleep_mtx, &ts);
			vcpu_lock(vcpu);
			pthread_mutex_unlock(&vcpu->vcpu_sleep_mtx);
			//msleep_spin(vcpu, &vcpu->mtx, "vmsusp", hz);

			vcpu_require_state_locked(vcpu, VCPU_FROZEN);
		} else {
			VCPU_CTR0(vm, vcpuid, "Rendezvous during suspend");
			vcpu_unlock(vcpu);
			vm_handle_rendezvous(vm, vcpuid);
			vcpu_lock(vcpu);
		}
	}
	vcpu_unlock(vcpu);

	/*
	 * Wakeup the other sleeping vcpus and return to userspace.
	 */
	for (i = 0; i < VM_MAXCPU; i++) {
		if (CPU_ISSET(((unsigned) i), &vm->suspended_cpus)) {
			vcpu_notify_event(vm, i, false);
		}
	}

	*retu = true;
	return (0);
}

int
vm_suspend(struct vm *vm, enum vm_suspend_how how)
{
	int i;

	if (how <= VM_SUSPEND_NONE || how >= VM_SUSPEND_LAST)
		return (EINVAL);

	if (atomic_cmpset_int(((volatile u_int *) &vm->suspend), 0, how) == 0) {
		VM_CTR2(vm, "virtual machine already suspended %d/%d",
		    vm->suspend, how);
		return (EALREADY);
	}

	VM_CTR1(vm, "virtual machine successfully suspended %d", how);

	/*
	 * Notify all active vcpus that they are now suspended.
	 */
	for (i = 0; i < VM_MAXCPU; i++) {
		if (CPU_ISSET(((unsigned) i), &vm->active_cpus))
			vcpu_notify_event(vm, i, false);
	}

	return (0);
}
Ejemplo n.º 11
0
/* Process remote control char */
static void remote_control(vtty_t *vtty,u_char c)
{
   vm_instance_t *vm = vtty->vm;
   cpu_gen_t *cpu0;
  
   cpu0 = vm->boot_cpu;

   /* Specific commands for the different CPU models */
   if (cpu0) {
      switch(cpu0->type) {
         case CPU_TYPE_MIPS64:
            if (remote_control_mips64(vtty,c,CPU_MIPS64(cpu0)))
               return;
            break;
         case CPU_TYPE_PPC32:
            if (remote_control_ppc32(vtty,c,CPU_PPC32(cpu0)))
               return;
            break;
      }
   }

   switch(c) {
      /* Show the object list */
      case 'o':
         vm_object_dump(vm);
         break;
  
      /* Stop the MIPS VM */
      case 'q':
         vm->status = VM_STATUS_SHUTDOWN;
         break;
  
      /* Reboot the C7200 */
      case 'k':
#if 0
         if (vm->type == VM_TYPE_C7200)
            c7200_boot_ios(VM_C7200(vm));
#endif
         break;
  
      /* Show the device list */
      case 'd':
         dev_show_list(vm);
         pci_dev_show_list(vm->pci_bus[0]);
         pci_dev_show_list(vm->pci_bus[1]);
         break;

      /* Show info about Port Adapters or Network Modules */
      case 'p':
         vm_slot_show_all_info(vm);
         break;
  
      /* Dump the MIPS registers */
      case 'r':
         if (cpu0) cpu0->reg_dump(cpu0);
         break;

      /* Dump the latest memory accesses */
      case 'm':
         if (cpu0) memlog_dump(cpu0);
         break;      
         
      /* Suspend CPU emulation */
      case 's':
         vm_suspend(vm);
         break;
  
      /* Resume CPU emulation */
      case 'u':
         vm_resume(vm);
         break;
  
      /* Dump the MMU information */
      case 't':
         if (cpu0) cpu0->mmu_dump(cpu0);
         break;
  
      /* Dump the MMU information (raw mode) */
      case 'z':
         if (cpu0) cpu0->mmu_raw_dump(cpu0);
         break;

      /* Memory translation cache statistics */
      case 'l':
         if (cpu0) cpu0->mts_show_stats(cpu0);
         break;

      /* Extract the configuration from the NVRAM */
      case 'c':
         vm_ios_save_config(vm);
         break;
  
      /* Determine an idle pointer counter */
      case 'i':
         if (cpu0)
            cpu0->get_idling_pc(cpu0);
         break;
  
      /* Experimentations / Tests */
      case 'x':

#if 0
         if (cpu0) {
            /* IRQ triggering */
            vm_set_irq(vm,6);
            //CPU_MIPS64(cpu0)->irq_disable = TRUE;
         }
#endif
#ifdef USE_UNSTABLE
         tsg_show_stats();
#endif
         break;

      case 'y':
         if (cpu0) {
            /* IRQ clearing */
            vm_clear_irq(vm,6);
         }
         break;

      /* Twice Ctrl + ']' (0x1d, 29), or Alt-Gr + '*' (0xb3, 179) */
      case 0x1d:
      case 0xb3:
         vtty_store(vtty,c);
         break;
         
      default:
         printf("\n\nInstance %s (ID %d)\n\n",vm->name,vm->instance_id);
         
         printf("o     - Show the VM object list\n"
                "d     - Show the device list\n"
                "r     - Dump CPU registers\n"
                "t     - Dump MMU information\n"
                "z     - Dump MMU information (raw mode)\n"
                "m     - Dump the latest memory accesses\n"
                "s     - Suspend CPU emulation\n"
                "u     - Resume CPU emulation\n"
                "q     - Quit the emulator\n"
                "k     - Reboot the virtual machine\n"
                "b     - Show info about JIT compiled pages\n"
                "l     - MTS cache statistics\n"
                "c     - Write IOS configuration to disk\n"
                "j     - Non-JIT mode statistics\n"
                "i     - Determine an idling pointer counter\n"
                "x     - Experimentations (can crash the box!)\n"
                "^]    - Send ^]\n"
                "Other - This help\n");
   }
}
Ejemplo n.º 12
0
int main(int argc,char *argv[])
{
   vm_instance_t *vm;

#ifdef PROFILE
   atexit(profiler_savestat);
#endif

   printf("Cisco Router Simulation Platform (version %s)\n",sw_version);
   printf("Copyright (c) 2005-2007 Christophe Fillot.\n");
   printf("Build date: %s %s\n\n",__DATE__,__TIME__);

   /* Register platforms */
   register_default_platforms();

   /* Initialize timers */
   timer_init();

   /* Initialize object registry */
   registry_init();
   
   /* Initialize ATM module (for HEC checksums) */
   atm_init();

   /* Initialize CRC functions */
   crc_init();

   /* Initialize NetIO code */
   netio_rxl_init();

   /* Initialize NetIO packet filters */
   netio_filter_load_all();

   /* Initialize VTTY code */
   vtty_init();
   
   /* Parse standard command line */
   if (!run_hypervisor(argc,argv))
      parse_std_cmd_line(argc,argv);

   /* Create general log file */
   create_log_file();

   /* Periodic tasks initialization */
   if (ptask_init(0) == -1)
      exit(EXIT_FAILURE);

   /* Create instruction lookup tables */
   mips64_jit_create_ilt();
   mips64_exec_create_ilt();
   ppc32_jit_create_ilt();
   ppc32_exec_create_ilt();
   
   setup_signals();

   if (!hypervisor_mode) {
      /* Initialize the default instance */
      vm = vm_acquire("default");
      assert(vm != NULL);

      if (vm->platform->init_instance(vm) == -1) {
         fprintf(stderr,"Unable to initialize router instance.\n");
         exit(EXIT_FAILURE);
      }

      /* Start GDB server before the image to allow debugging from
         the begining of it's execution */ 
      if (vm->gdb_server_running)
      {
        /* Stop main CPU */
        vm_suspend(vm);
//         cpu_stop(vm->boot_cpu);
      
        if (gdb_server_start_listener(vm) < 0) {
            fprintf(stderr,"GDB server unable to create TCP sockets.\n");
            exit(EXIT_FAILURE);
        }
      }

#if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0)
      {
         m_uint32_t counter,prev = 0,delta;
         while(vm->status == VM_STATUS_RUNNING) {
            counter = cpu_get_perf_counter(vm->boot_cpu);
            delta = counter - prev;
            prev = counter;
            printf("delta = %u\n",delta);
            sleep(1);
         }
      }
#else
      /* Start instance monitoring */
      vm_monitor(vm);
#endif

      // FIXME: remove this kludge
      if (vm->gdb_server_running)
      {
         //while (vm->gdb_conn->active)
         //   usleep(1000000);
         gdb_server_close_control_sockets();
      }

      /* Free resources used by instance */
      vm_release(vm);

   } else {
      hypervisor_tcp_server(hypervisor_ip_address,hypervisor_tcp_port);
   }

   dynamips_reset();
   close_log_file();
   return(0);
}
Ejemplo n.º 13
0
int
xh_vm_suspend(enum vm_suspend_how how)
{
	return (vm_suspend(vm, how));
}
Ejemplo n.º 14
0
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);
}