X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm.c;h=e16e2fa60f580e7b36f00f8e3fe1f66b393b7d4d;hb=928297a7cf5ffbf3a210fcaf7556e681bbb436d5;hp=cfef4f91c031535ba913f167f707fe2f5f92f436;hpb=b07dd4e35a37f1db04c4f52f9904ee7206673ac6;p=palacios.git diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index cfef4f9..e16e2fa 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef V3_CONFIG_SVM #include @@ -55,6 +56,8 @@ int v3_dbg_enable = 0; static void init_cpu(void * arg) { uint32_t cpu_id = (uint32_t)(addr_t)arg; + v3_init_fp(); + #ifdef V3_CONFIG_SVM if (v3_is_svm_capable()) { PrintDebug(VM_NONE, VCORE_NONE, "Machine is SVM Capable\n"); @@ -100,8 +103,22 @@ static void deinit_cpu(void * arg) { PrintError(VM_NONE, VCORE_NONE, "CPU has no virtualization Extensions\n"); break; } + + v3_deinit_fp(); + } + +static int in_long_mode() +{ + uint32_t high, low; + + v3_get_msr(0xc0000080,&high,&low); // EFER + + return ((low & 0x500)== 0x500); // LMA and LME set +} + + void Init_V3(struct v3_os_hooks * hooks, char * cpu_mask, int num_cpus, char *options) { int i = 0; int minor = 0; @@ -110,6 +127,16 @@ void Init_V3(struct v3_os_hooks * hooks, char * cpu_mask, int num_cpus, char *op V3_Print(VM_NONE, VCORE_NONE, "V3 Print statement to fix a Kitten page fault bug\n"); + +#ifndef __V3_64BIT__ +#error Palacios does not support compilation for a 32 bit host OS!!!! +#else + if (!in_long_mode()) { + PrintError(VM_NONE,VCORE_NONE,"Palacios supports execution only in long mode (64 bit).\n"); + return; + } +#endif + // Set global variables. os_hooks = hooks; @@ -136,6 +163,10 @@ void Init_V3(struct v3_os_hooks * hooks, char * cpu_mask, int num_cpus, char *op // Register all shadow paging handlers V3_init_shdw_paging(); +#ifdef V3_CONFIG_SWAPPING + v3_init_swapping(); +#endif + // Initialize the cpu_mapper framework (must be before extensions) V3_init_cpu_mapper(); @@ -213,6 +244,10 @@ void Shutdown_V3() { V3_deinit_scheduling(); V3_deinit_cpu_mapper(); + +#ifdef V3_CONFIG_SWAPPING + v3_deinit_swapping(); +#endif V3_deinit_shdw_paging(); @@ -305,34 +340,17 @@ static int start_core(void * p) int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { - uint32_t i,j; + uint32_t i; uint8_t * core_mask = (uint8_t *)&cpu_mask; // This is to make future expansion easier uint32_t avail_cores = 0; int vcore_id = 0; - extern uint64_t v3_mem_block_size; - if (vm->run_state != VM_STOPPED) { PrintError(vm, VCORE_NONE, "VM has already been launched (state=%d)\n", (int)vm->run_state); return -1; } - - // Do not run if any core is using shadow paging and we are out of 4 GB bounds - for (i=0;inum_cores;i++) { - if (vm->cores[i].shdw_pg_mode == SHADOW_PAGING) { - for (j=0;jmem_map.num_base_regions;j++) { - if ((vm->mem_map.base_regions[i].host_addr + v3_mem_block_size) >= 0x100000000ULL) { - PrintError(vm, VCORE_NONE, "Base memory region %d exceeds 4 GB boundary with shadow paging enabled on core %d.\n",j, i); - PrintError(vm, VCORE_NONE, "Any use of non-64 bit mode in the guest is likely to fail in this configuration.\n"); - PrintError(vm, VCORE_NONE, "If you would like to proceed anyway, remove this check and recompile Palacios.\n"); - PrintError(vm, VCORE_NONE, "Alternatively, change this VM to use nested paging.\n"); - return -1; - } - } - } - } - + /// CHECK IF WE ARE MULTICORE ENABLED.... V3_Print(vm, VCORE_NONE, "V3 -- Starting VM (%u cores)\n", vm->num_cores); @@ -378,7 +396,14 @@ int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask) { PrintDebug(vm, VCORE_NONE, "run: core=%u, func=0x%p, arg=0x%p, name=%s\n", core->pcpu_id, start_core, core, core->exec_name); - core->core_run_state = CORE_STOPPED; // core zero will turn itself on + if (core->core_run_state==CORE_INVALID) { + // launch of a fresh VM + core->core_run_state = CORE_STOPPED; + // core zero will turn itself on + } else { + // this is a resume - use whatever its current run_state is + } + core->core_thread = V3_CREATE_THREAD_ON_CPU(core->pcpu_id, start_core, core, core->exec_name); if (core->core_thread == NULL) { @@ -552,12 +577,10 @@ int v3_move_vm_mem(struct v3_vm_info * vm, void *gpa, int target_cpu) { // region uses exclusive addressing [guest_start,guest_end) num_pages = (reg->guest_end-reg->guest_start)/PAGE_SIZE; - // Now we allocate space for the new region with the same constraints as - // it originally had new_hpa = V3_AllocPagesExtended(num_pages, PAGE_SIZE_4KB, new_node, - reg->flags.limit32 ? V3_ALLOC_PAGES_CONSTRAINT_4GB : 0); + 0); // no constraints given new shadow pager impl if (!new_hpa) { PrintError(vm, VCORE_NONE, "Cannot allocate memory for new base region...\n"); @@ -580,7 +603,7 @@ int v3_move_vm_mem(struct v3_vm_info * vm, void *gpa, int target_cpu) { v3_invalidate_shadow_pts(&(vm->cores[i])); } else if (vm->cores[i].shdw_pg_mode==NESTED_PAGING) { // nested invalidator uses inclusive addressing [start,end], not [start,end) - v3_invalidate_nested_addr_range(&(vm->cores[i]),reg->guest_start,reg->guest_end-1); + v3_invalidate_nested_addr_range(&(vm->cores[i]),reg->guest_start,reg->guest_end-1,NULL,NULL); } else { PrintError(vm,VCORE_NONE, "Cannot determine how to invalidate paging structures! Reverting to previous region.\n"); // We'll restore things... @@ -689,6 +712,7 @@ static int sim_callback(struct guest_info * core, void * private_data) { V3_Print(core->vm_info, core, "Simulation callback activated (guest_rip=%p)\n", (void *)core->rip); while (v3_bitmap_check(timeout_map, core->vcpu_id) == 1) { + // We spin here if there is noone to yield to v3_yield(NULL,-1); } @@ -759,7 +783,8 @@ int v3_simulate_vm(struct v3_vm_info * vm, unsigned int msecs) { if (all_blocked == 1) { break; } - + + // Intentionally spin if there is no one to yield to v3_yield(NULL,-1); } @@ -837,6 +862,14 @@ int v3_get_state_vm(struct v3_vm_info *vm, for (i=0;imem_map.num_base_regions;i++) { mem->region[i].host_paddr = (void*)(vm->mem_map.base_regions[i].host_addr); mem->region[i].size = v3_mem_block_size; +#ifdef V3_CONFIG_SWAPPING + mem->region[i].swapped = vm->mem_map.base_regions[i].flags.swapped; + mem->region[i].pinned = vm->mem_map.base_regions[i].flags.pinned; +#else + mem->region[i].swapped = 0; + mem->region[i].pinned = 0; +#endif + } mem->num_regions=numregions;