};
+typedef enum {V3_VM_UNKNOWN, V3_VM_INVALID, V3_VM_RUNNING, V3_VM_STOPPED, V3_VM_PAUSED, V3_VM_ERROR, V3_VM_SIMULATING} v3_vm_state_t;
+typedef enum {V3_VCORE_UNKNOWN, V3_VCORE_INVALID, V3_VCORE_RUNNING, V3_VCORE_STOPPED} v3_vcore_state_t;
+typedef enum {V3_VCORE_CPU_UNKNOWN, V3_VCORE_CPU_REAL, V3_VCORE_CPU_PROTECTED, V3_VCORE_CPU_PROTECTED_PAE, V3_VCORE_CPU_LONG, V3_VCORE_CPU_LONG_32_COMPAT, V3_VCORE_CPU_LONG_16_COMPAT} v3_vcore_cpu_mode_t;
+
+typedef enum {V3_VCORE_MEM_STATE_UNKNOWN, V3_VCORE_MEM_STATE_SHADOW, V3_VCORE_MEM_STATE_NESTED} v3_vcore_mem_state_t;
+typedef enum {V3_VCORE_MEM_MODE_UNKNOWN, V3_VCORE_MEM_MODE_PHYSICAL, V3_VCORE_MEM_MODE_VIRTUAL} v3_vcore_mem_mode_t;
+
+struct v3_vcore_state {
+ v3_vcore_state_t state;
+ v3_vcore_cpu_mode_t cpu_mode;
+ v3_vcore_mem_state_t mem_state;
+ v3_vcore_mem_mode_t mem_mode;
+ unsigned long pcore;
+ void * last_rip;
+ unsigned long long num_exits;
+};
+struct v3_vm_state {
+ v3_vm_state_t state;
+ void * mem_base_paddr;
+ unsigned long long mem_size;
+ unsigned long num_vcores;
+ struct v3_vcore_state vcore[0];
+};
void Init_V3(struct v3_os_hooks * hooks, char * cpus, int num_cpus);
void Shutdown_V3( void );
int v3_continue_vm(struct v3_vm_info * vm);
int v3_simulate_vm(struct v3_vm_info * vm, unsigned int msecs);
-
int v3_save_vm(struct v3_vm_info * vm, char * store, char * url);
int v3_load_vm(struct v3_vm_info * vm, char * store, char * url);
int v3_move_vm_core(struct v3_vm_info * vm, int vcore_id, int target_cpu);
-
int v3_free_vm(struct v3_vm_info * vm);
+int v3_get_state_vm(struct v3_vm_info *vm, struct v3_vm_state *out);
+
int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr);
}
+int v3_get_state_vm(struct v3_vm_info *vm, struct v3_vm_state *s)
+{
+ uint32_t i;
+ uint32_t numcores = s->num_vcores > vm->num_cores ? vm->num_cores : s->num_vcores;
+
+ switch (vm->run_state) {
+ case VM_INVALID: s->state = V3_VM_INVALID; break;
+ case VM_RUNNING: s->state = V3_VM_RUNNING; break;
+ case VM_STOPPED: s->state = V3_VM_STOPPED; break;
+ case VM_PAUSED: s->state = V3_VM_PAUSED; break;
+ case VM_ERROR: s->state = V3_VM_ERROR; break;
+ case VM_SIMULATING: s->state = V3_VM_SIMULATING; break;
+ default: s->state = V3_VM_UNKNOWN; break;
+ }
+
+ s->mem_base_paddr = (void*)(vm->mem_map.base_region.host_addr);
+ s->mem_size = vm->mem_size;
+
+ s->num_vcores = numcores;
+
+ for (i=0;i<numcores;i++) {
+ switch (vm->cores[i].core_run_state) {
+ case CORE_INVALID: s->vcore[i].state = V3_VCORE_INVALID; break;
+ case CORE_RUNNING: s->vcore[i].state = V3_VCORE_RUNNING; break;
+ case CORE_STOPPED: s->vcore[i].state = V3_VCORE_STOPPED; break;
+ default: s->vcore[i].state = V3_VCORE_UNKNOWN; break;
+ }
+ switch (vm->cores[i].cpu_mode) {
+ case REAL: s->vcore[i].cpu_mode = V3_VCORE_CPU_REAL; break;
+ case PROTECTED: s->vcore[i].cpu_mode = V3_VCORE_CPU_PROTECTED; break;
+ case PROTECTED_PAE: s->vcore[i].cpu_mode = V3_VCORE_CPU_PROTECTED_PAE; break;
+ case LONG: s->vcore[i].cpu_mode = V3_VCORE_CPU_LONG; break;
+ case LONG_32_COMPAT: s->vcore[i].cpu_mode = V3_VCORE_CPU_LONG_32_COMPAT; break;
+ case LONG_16_COMPAT: s->vcore[i].cpu_mode = V3_VCORE_CPU_LONG_16_COMPAT; break;
+ default: s->vcore[i].cpu_mode = V3_VCORE_CPU_UNKNOWN; break;
+ }
+ switch (vm->cores[i].shdw_pg_mode) {
+ case SHADOW_PAGING: s->vcore[i].mem_state = V3_VCORE_MEM_STATE_SHADOW; break;
+ case NESTED_PAGING: s->vcore[i].mem_state = V3_VCORE_MEM_STATE_NESTED; break;
+ default: s->vcore[i].mem_state = V3_VCORE_MEM_STATE_UNKNOWN; break;
+ }
+ switch (vm->cores[i].mem_mode) {
+ case PHYSICAL_MEM: s->vcore[i].mem_mode = V3_VCORE_MEM_MODE_PHYSICAL; break;
+ case VIRTUAL_MEM: s->vcore[i].mem_mode=V3_VCORE_MEM_MODE_VIRTUAL; break;
+ default: s->vcore[i].mem_mode=V3_VCORE_MEM_MODE_UNKNOWN; break;
+ }
+
+ s->vcore[i].pcore=vm->cores[i].pcpu_id;
+ s->vcore[i].last_rip=(void*)(vm->cores[i].rip);
+ s->vcore[i].num_exits=vm->cores[i].num_exits;
+ }
+
+ return 0;
+}
+
+
#ifdef V3_CONFIG_CHECKPOINT
#include <palacios/vmm_checkpoint.h>