X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fsvm_handler.c;h=78f62e8cdbfdee224023cef06ec4e48c1c1f8ff9;hb=c5ba903ae97ea49bbac5b660f76d2031c5302a3d;hp=5849055c26dbf103932bf84de1395bc66223d055;hpb=164bd99da7605dfb5f8a56338e54c924b2a583a6;p=palacios.git diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 5849055..78f62e8 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,10 @@ #include #include +#ifdef V3_CONFIG_TM_FUNC +#include +#endif + #ifndef V3_CONFIG_DEBUG_SVM #undef PrintDebug #define PrintDebug(fmt, args...) @@ -55,9 +60,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i } #endif - - - // PrintDebug("SVM Returned: Exit Code: %p\n", (void *)exit_code); + // PrintDebug(info->vm_info, info, "SVM Returned: Exit Code: %p\n", (void *)exit_code); switch (exit_code) { case SVM_EXIT_IOIO: { @@ -103,7 +106,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } } else { - PrintError("Invalid MSR Operation\n"); + PrintError(info->vm_info, info, "Invalid MSR Operation\n"); return -1; } @@ -111,14 +114,14 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i case SVM_EXIT_CPUID: if (v3_handle_cpuid(info) == -1) { - PrintError("Error handling CPUID\n"); + PrintError(info->vm_info, info, "Error handling CPUID\n"); return -1; } break; case SVM_EXIT_CR0_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR0 Write\n"); + PrintDebug(info->vm_info, info, "CR0 Write\n"); #endif if (v3_handle_cr0_write(info) == -1) { return -1; @@ -126,7 +129,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_CR0_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR0 Read\n"); + PrintDebug(info->vm_info, info, "CR0 Read\n"); #endif if (v3_handle_cr0_read(info) == -1) { return -1; @@ -134,7 +137,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_CR3_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR3 Write\n"); + PrintDebug(info->vm_info, info, "CR3 Write\n"); #endif if (v3_handle_cr3_write(info) == -1) { return -1; @@ -143,7 +146,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_CR3_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR3 Read\n"); + PrintDebug(info->vm_info, info, "CR3 Read\n"); #endif if (v3_handle_cr3_read(info) == -1) { return -1; @@ -151,7 +154,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_CR4_WRITE: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR4 Write\n"); + PrintDebug(info->vm_info, info, "CR4 Write\n"); #endif if (v3_handle_cr4_write(info) == -1) { return -1; @@ -159,17 +162,36 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_CR4_READ: #ifdef V3_CONFIG_DEBUG_CTRL_REGS - PrintDebug("CR4 Read\n"); + PrintDebug(info->vm_info, info, "CR4 Read\n"); #endif if (v3_handle_cr4_read(info) == -1) { return -1; } break; + + case SVM_EXIT_CR8_WRITE: +#ifdef V3_CONFIG_DEBUG_CTRL_REGS + PrintDebug(info->vm_info, info, "CR8 Read\n"); +#endif + if (v3_handle_cr8_read(info) == -1) { + return -1; + } + break; + + case SVM_EXIT_CR8_READ: +#ifdef V3_CONFIG_DEBUG_CTRL_REGS + PrintDebug(info->vm_info, info, "CR8 Read\n"); +#endif + if (v3_handle_cr8_read(info) == -1) { + return -1; + } + break; + case SVM_EXIT_EXCP14: { addr_t fault_addr = exit_info2; pf_error_t * error_code = (pf_error_t *)&(exit_info1); #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING - PrintDebug("PageFault at %p (error=%d)\n", + PrintDebug(info->vm_info, info, "PageFault at %p (error=%d)\n", (void *)fault_addr, *(uint_t *)error_code); #endif if (info->shdw_pg_mode == SHADOW_PAGING) { @@ -177,21 +199,43 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } } else { - PrintError("Page fault in un implemented paging mode\n"); + PrintError(info->vm_info, info, "Page fault in un implemented paging mode\n"); return -1; } break; } + +#ifdef V3_CONFIG_TM_FUNC + case SVM_EXIT_EXCP6: + case SVM_EXIT_EXCP0: + case SVM_EXIT_EXCP1: + case SVM_EXIT_EXCP3: + case SVM_EXIT_EXCP4: + case SVM_EXIT_EXCP5: + case SVM_EXIT_EXCP7: + case SVM_EXIT_EXCP10: + case SVM_EXIT_EXCP11: + case SVM_EXIT_EXCP12: + case SVM_EXIT_EXCP13: + case SVM_EXIT_EXCP16: + case SVM_EXIT_EXCP17: + case SVM_EXIT_EXCP19: + if (v3_tm_handle_exception(info, exit_code) == -1) { + return -1; + } + break; +#endif + case SVM_EXIT_NPF: { addr_t fault_addr = exit_info2; pf_error_t * error_code = (pf_error_t *)&(exit_info1); if (info->shdw_pg_mode == NESTED_PAGING) { - if (v3_handle_nested_pagefault(info, fault_addr, *error_code) == -1) { + if (v3_handle_nested_pagefault(info, fault_addr, error_code, NULL, NULL) == -1) { return -1; } } else { - PrintError("Currently unhandled Nested Page Fault\n"); + PrintError(info->vm_info, info, "Currently unhandled Nested Page Fault\n"); return -1; } break; @@ -199,7 +243,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i case SVM_EXIT_INVLPG: if (info->shdw_pg_mode == SHADOW_PAGING) { #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING - PrintDebug("Invlpg\n"); + PrintDebug(info->vm_info, info, "Invlpg\n"); #endif if (v3_handle_shadow_invlpg(info) == -1) { return -1; @@ -216,7 +260,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i info->rip += 3; if (v3_handle_hypercall(info) == -1) { - PrintError("Error handling Hypercall\n"); + PrintError(info->vm_info, info, "Error handling Hypercall\n"); return -1; } @@ -232,21 +276,41 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_HLT: #ifdef V3_CONFIG_DEBUG_HALT - PrintDebug("Guest halted\n"); + PrintDebug(info->vm_info, info, "Guest halted\n"); #endif if (v3_handle_halt(info) == -1) { return -1; } break; + + case SVM_EXIT_MONITOR: +#ifdef V3_CONFIG_DEBUG_MWAIT + PrintDebug(info->vm_info, info, "Guest issuing MONITOR\n"); +#endif + if (v3_handle_monitor(info) == -1) { + return -1; + } + break; + + case SVM_EXIT_MWAIT: + case SVM_EXIT_MWAIT_CONDITIONAL: +#ifdef V3_CONFIG_DEBUG_MWAIT + PrintDebug(info->vm_info, info, "Guest issuing MWAIT\n"); +#endif + if (v3_handle_mwait(info) == -1) { + return -1; + } + break; + case SVM_EXIT_PAUSE: - // PrintDebug("Guest paused\n"); + // PrintDebug(info->vm_info, info, "Guest paused\n"); if (v3_handle_svm_pause(info) == -1) { return -1; } break; case SVM_EXIT_WBINVD: #ifdef V3_CONFIG_DEBUG_EMULATOR - PrintDebug("WBINVD\n"); + PrintDebug(info->vm_info, info, "WBINVD\n"); #endif if (v3_handle_svm_wbinvd(info) == -1) { return -1; @@ -254,24 +318,25 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i break; case SVM_EXIT_RDTSC: #ifdef V3_CONFIG_DEBUG_TIME - PrintDebug("RDTSC/RDTSCP\n"); + PrintDebug(info->vm_info, info, "RDTSC/RDTSCP\n"); #endif if (v3_handle_rdtsc(info) == -1) { - PrintError("Error Handling RDTSC instruction\n"); + PrintError(info->vm_info, info, "Error Handling RDTSC instruction\n"); return -1; } break; case SVM_EXIT_RDTSCP: #ifdef V3_CONFIG_DEBUG_TIME - PrintDebug("RDTSCP\n"); + PrintDebug(info->vm_info, info, "RDTSCP\n"); #endif if (v3_handle_rdtscp(info) == -1) { - PrintError("Error Handling RDTSCP instruction\n"); + PrintError(info->vm_info, info, "Error handling RDTSCP instruction\n"); return -1; } + break; case SVM_EXIT_SHUTDOWN: - PrintDebug("Guest-initiated shutdown\n"); + PrintDebug(info->vm_info, info, "Guest-initiated shutdown\n"); info->vm_info->run_state = VM_STOPPED; @@ -281,10 +346,10 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i #ifdef V3_CONFIG_EXT_SW_INTERRUPTS case SVM_EXIT_SWINT: #ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS - PrintDebug("Intercepted a software interrupt\n"); + PrintDebug(info->vm_info, info, "Intercepted a software interrupt\n"); #endif if (v3_handle_swintr(info) == -1) { - PrintError("Error handling software interrupt\n"); + PrintError(info->vm_info, info, "Error handling software interrupt\n"); return -1; } break; @@ -298,22 +363,22 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i addr_t rip_addr; - PrintError("Unhandled SVM Exit: %s\n", v3_svm_exit_code_to_str(exit_code)); + PrintError(info->vm_info, info, "Unhandled SVM Exit: %s\n", v3_svm_exit_code_to_str(exit_code)); rip_addr = get_addr_linear(info, info->rip, &(info->segments.cs)); - PrintError("SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); - PrintError("RIP: %p\n", (void *)(addr_t)(info->rip)); - PrintError("RIP Linear: %p\n", (void *)(addr_t)(rip_addr)); + PrintError(info->vm_info, info, "SVM Returned:(VMCB=%p)\n", (void *)(info->vmm_data)); + PrintError(info->vm_info, info, "RIP: %p\n", (void *)(addr_t)(info->rip)); + PrintError(info->vm_info, info, "RIP Linear: %p\n", (void *)(addr_t)(rip_addr)); - PrintError("SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); + PrintError(info->vm_info, info, "SVM Returned: Exit Code: %p\n", (void *)(addr_t)exit_code); - PrintError("io_info1 low = 0x%.8x\n", *(uint_t*)&(exit_info1)); - PrintError("io_info1 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info1)) + 4)); + PrintError(info->vm_info, info, "io_info1 low = 0x%.8x\n", *(uint_t*)&(exit_info1)); + PrintError(info->vm_info, info, "io_info1 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info1)) + 4)); - PrintError("io_info2 low = 0x%.8x\n", *(uint_t*)&(exit_info2)); - PrintError("io_info2 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info2)) + 4)); + PrintError(info->vm_info, info, "io_info2 low = 0x%.8x\n", *(uint_t*)&(exit_info2)); + PrintError(info->vm_info, info, "io_info2 high = 0x%.8x\n", *(uint_t *)(((uint8_t *)&(exit_info2)) + 4)); if (info->shdw_pg_mode == SHADOW_PAGING) { @@ -334,7 +399,7 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i if (exit_code == SVM_EXIT_INTR) { - //PrintDebug("INTR ret IP = %x\n", guest_state->rip); + //PrintDebug(info->vm_info, info, "INTR ret IP = %x\n", guest_state->rip); } return 0;