X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmx.c;h=4722fb51c58f1d925772a3dd0d6c50bc492e97d2;hb=d662cc4cc19794e57b3a0126fd05d09456e22cdc;hp=29f1ccf8e05780fba4fc60ee86bab8f44bd08110;hpb=5bf6d0c260240e314876a2fca8e3fd56bd6a1029;p=palacios.git diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 29f1ccf..4722fb5 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -199,8 +199,7 @@ static int init_vmcs_bios(struct guest_info * info, struct vmx_data * vmx_state) /********** Setup and VMX Control Fields from MSR ***********/ /* Setup IO map */ - v3_init_vmx_io_map(info); - v3_init_vmx_msr_map(info); + struct v3_msr tmp_msr; @@ -220,11 +219,12 @@ static int init_vmcs_bios(struct guest_info * info, struct vmx_data * vmx_state) vmx_state->pri_proc_ctrls.use_msr_bitmap = 1; vmx_state->pri_proc_ctrls.pause_exit = 1; - vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_A_ADDR, (addr_t)V3_PAddr(info->io_map.arch_data)); + vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_A_ADDR, (addr_t)V3_PAddr(info->vm_info->io_map.arch_data)); vmx_ret |= check_vmcs_write(VMCS_IO_BITMAP_B_ADDR, - (addr_t)V3_PAddr(info->io_map.arch_data) + PAGE_SIZE_4KB); + (addr_t)V3_PAddr(info->vm_info->io_map.arch_data) + PAGE_SIZE_4KB); + - vmx_ret |= check_vmcs_write(VMCS_MSR_BITMAP, (addr_t)V3_PAddr(info->msr_map.arch_data)); + vmx_ret |= check_vmcs_write(VMCS_MSR_BITMAP, (addr_t)V3_PAddr(info->vm_info->msr_map.arch_data)); v3_get_msr(VMX_EXIT_CTLS_MSR, &(tmp_msr.hi), &(tmp_msr.lo)); vmx_state->exit_ctrls.value = tmp_msr.lo; @@ -453,12 +453,12 @@ static int update_irq_exit_state(struct guest_info * info) { check_vmcs_read(VMCS_IDT_VECTOR_INFO, &(idt_vec_info.value)); - if ((info->intr_state.irq_started == 1) && (idt_vec_info.valid == 0)) { + if ((info->intr_core_state.irq_started == 1) && (idt_vec_info.valid == 0)) { #ifdef CONFIG_DEBUG_INTERRUPTS PrintDebug("Calling v3_injecting_intr\n"); #endif - info->intr_state.irq_started = 0; - v3_injecting_intr(info, info->intr_state.irq_vector, V3_EXTERNAL_IRQ); + info->intr_core_state.irq_started = 0; + v3_injecting_intr(info, info->intr_core_state.irq_vector, V3_EXTERNAL_IRQ); } return 0; @@ -466,9 +466,11 @@ static int update_irq_exit_state(struct guest_info * info) { static int update_irq_entry_state(struct guest_info * info) { struct vmx_exit_idt_vec_info idt_vec_info; + struct vmcs_interrupt_state intr_core_state; struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data); check_vmcs_read(VMCS_IDT_VECTOR_INFO, &(idt_vec_info.value)); + check_vmcs_read(VMCS_GUEST_INT_STATE, &(intr_core_state)); /* Check for pending exceptions to inject */ if (v3_excp_pending(info)) { @@ -498,9 +500,10 @@ static int update_irq_entry_state(struct guest_info * info) { v3_injecting_excp(info, int_info.vector); - } else if (((struct rflags *)&(info->ctrl_regs.rflags))->intr == 1) { + } else if ((((struct rflags *)&(info->ctrl_regs.rflags))->intr == 1) && + (intr_core_state.val == 0)) { - if ((info->intr_state.irq_started == 1) && (idt_vec_info.valid == 1)) { + if ((info->intr_core_state.irq_started == 1) && (idt_vec_info.valid == 1)) { #ifdef CONFIG_DEBUG_INTERRUPTS PrintDebug("IRQ pending from previous injection\n"); @@ -523,21 +526,21 @@ static int update_irq_entry_state(struct guest_info * info) { switch (v3_intr_pending(info)) { case V3_EXTERNAL_IRQ: { - info->intr_state.irq_vector = v3_get_intr(info); - ent_int.vector = info->intr_state.irq_vector; + info->intr_core_state.irq_vector = v3_get_intr(info); + ent_int.vector = info->intr_core_state.irq_vector; ent_int.type = 0; ent_int.error_code = 0; ent_int.valid = 1; #ifdef CONFIG_DEBUG_INTERRUPTS PrintDebug("Injecting Interrupt %d at exit %u(EIP=%p)\n", - info->intr_state.irq_vector, + info->intr_core_state.irq_vector, (uint32_t)info->num_exits, (void *)info->rip); #endif check_vmcs_write(VMCS_ENTRY_INT_INFO, ent_int.value); - info->intr_state.irq_started = 1; + info->intr_core_state.irq_started = 1; break; } @@ -587,6 +590,35 @@ static int update_irq_entry_state(struct guest_info * info) { } + +static struct vmx_exit_info exit_log[10]; + +static void print_exit_log(struct guest_info * info) { + int cnt = info->num_exits % 10; + int i = 0; + + + V3_Print("\nExit Log (%d total exits):\n", (uint32_t)info->num_exits); + + for (i = 0; i < 10; i++) { + struct vmx_exit_info * tmp = &exit_log[cnt]; + + V3_Print("%d:\texit_reason = %p\n", i, (void *)(addr_t)tmp->exit_reason); + V3_Print("\texit_qual = %p\n", (void *)tmp->exit_qual); + V3_Print("\tint_info = %p\n", (void *)(addr_t)tmp->int_info); + V3_Print("\tint_err = %p\n", (void *)(addr_t)tmp->int_err); + V3_Print("\tinstr_info = %p\n", (void *)(addr_t)tmp->instr_info); + + cnt--; + + if (cnt == -1) { + cnt = 9; + } + + } + +} + /* * CAUTION and DANGER!!! * @@ -613,18 +645,23 @@ int v3_vmx_enter(struct guest_info * info) { #ifdef CONFIG_SYMBIOTIC - if (info->sym_state.sym_call_active == 0) { + if (info->sym_local_state.symcall_state.sym_call_active == 0) { update_irq_entry_state(info); } #else update_irq_entry_state(info); #endif + { + addr_t guest_cr3; + vmcs_read(VMCS_GUEST_CR3, &guest_cr3); + vmcs_write(VMCS_GUEST_CR3, guest_cr3); + } rdtscll(info->time_state.cached_host_tsc); - if (info->run_state == VM_STOPPED) { - info->run_state = VM_RUNNING; + if (info->vm_info->run_state == VM_STOPPED) { + info->vm_info->run_state = VM_RUNNING; ret = v3_vmx_launch(&(info->vm_regs), info, &(info->ctrl_regs)); } else { ret = v3_vmx_resume(&(info->vm_regs), info, &(info->ctrl_regs)); @@ -650,6 +687,8 @@ int v3_vmx_enter(struct guest_info * info) { /* Update guest state */ v3_vmx_save_vmcs(info); + // info->cpl = info->segments.cs.selector & 0x3; + info->mem_mode = v3_get_vm_mem_mode(info); info->cpu_mode = v3_get_vm_cpu_mode(info); @@ -664,9 +703,11 @@ int v3_vmx_enter(struct guest_info * info) { //PrintDebug("VMX Exit taken, id-qual: %u-%lu\n", exit_info.exit_reason, exit_info.exit_qual); + exit_log[info->num_exits % 10] = exit_info; + #ifdef CONFIG_SYMBIOTIC - if (info->sym_state.sym_call_active == 0) { + if (info->sym_local_state.symcall_state.sym_call_active == 0) { update_irq_exit_state(info); } #else @@ -699,12 +740,16 @@ int v3_start_vmx_guest(struct guest_info* info) { while (1) { if (v3_vmx_enter(info) == -1) { v3_print_vmcs(); + print_exit_log(info); return -1; } +/* if ((info->num_exits % 5000) == 0) { - V3_Print("SVM Exit number %d\n", (uint32_t)info->num_exits); + V3_Print("VMX Exit number %d\n", (uint32_t)info->num_exits); } +*/ + } return 0; @@ -749,7 +794,7 @@ void v3_init_vmx_cpu(int cpu_id) { uint64_t ret = 0; v3_get_msr(VMX_CR4_FIXED0_MSR,&(tmp_msr.hi),&(tmp_msr.lo)); - +#ifdef __V3_64BIT__ __asm__ __volatile__ ( "movq %%cr4, %%rbx;" "orq $0x00002000, %%rbx;" @@ -778,6 +823,38 @@ void v3_init_vmx_cpu(int cpu_id) { : : "%rbx" ); +#elif __V3_32BIT__ + __asm__ __volatile__ ( + "movq %%cr4, %%ecx;" + "orq $0x00002000, %%ecx;" + "movq %%ecx, %0;" + : "=m"(ret) + : + : "%ecx" + ); + + if ((~ret & tmp_msr.value) == 0) { + __asm__ __volatile__ ( + "movq %0, %%cr4;" + : + : "q"(ret) + ); + } else { + PrintError("Invalid CR4 Settings!\n"); + return; + } + + __asm__ __volatile__ ( + "movq %%cr0, %%ecx; " + "orq $0x00000020,%%ecx; " + "movq %%ecx, %%cr0;" + : + : + : "%ecx" + ); + +#endif + // // Should check and return Error here....