From: Peter Dinda Date: Thu, 7 Aug 2008 22:51:53 +0000 (+0000) Subject: Added support for wbinvd instruction exit (which windows uses) X-Git-Tag: vmmhack1-ramdisk-boot-iso-puppy~11 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=851cedf7660970f7af19bffb63b1ba1d70f77e3e Added support for wbinvd instruction exit (which windows uses) Cleaned up svm_handler and added the list of unhandled exits for clarity (Everything is now a switch) --- diff --git a/palacios/src/palacios/svm_halt.c b/palacios/src/palacios/svm_halt.c index 3c893d3..9dda4fd 100644 --- a/palacios/src/palacios/svm_halt.c +++ b/palacios/src/palacios/svm_halt.c @@ -4,33 +4,42 @@ void Yield(void); +// +// This should trigger a #GP if cpl!=0, otherwise, yield to host +// + int handle_svm_halt(struct guest_info * info) { - // What we should do is starting waiting on an OS event that will - // result in an injection of an interrupt. - - // What we will hackishly do instead is resume on any event - // Plus is this totally GeekOS specific - - ullong_t yield_start = 0; - ullong_t yield_stop = 0; - uint32_t gap = 0; - - PrintDebug("GeekOS Yield\n"); - - rdtscll(yield_start); - Yield(); - rdtscll(yield_stop); - - - //v3_update_time(info, yield_stop - yield_start); - gap = yield_stop - yield_start; - v3_raise_irq(info, 0); - - PrintDebug("GeekOS Yield Done (%d cycles)\n", gap); - - info->rip+=1; - + if (info->cpl!=0) { + v3_raise_exception(info, GPF_EXCEPTION); + } else { + + // What we should do is starting waiting on an OS event that will + // result in an injection of an interrupt. + + // What we will hackishly do instead is resume on any event + // Plus is this totally GeekOS specific + + ullong_t yield_start = 0; + ullong_t yield_stop = 0; + uint32_t gap = 0; + + PrintDebug("GeekOS Yield\n"); + + rdtscll(yield_start); + Yield(); + rdtscll(yield_stop); + + + //v3_update_time(info, yield_stop - yield_start); + gap = yield_stop - yield_start; + v3_raise_irq(info, 0); + + PrintDebug("GeekOS Yield Done (%d cycles)\n", gap); + + info->rip+=1; + } + return 0; } diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index e634b2b..bd99a44 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -88,8 +89,10 @@ int handle_svm_exit(struct guest_info * info) { //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); - - if (exit_code == VMEXIT_IOIO) { + + switch (exit_code) { + + case VMEXIT_IOIO: { struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1); if (io_info->type == 0) { @@ -113,36 +116,51 @@ int handle_svm_exit(struct guest_info * info) { } } } - } else if (exit_code == VMEXIT_CR0_WRITE) { + } + break; + + + case VMEXIT_CR0_WRITE: { #ifdef DEBUG_CTRL_REGS PrintDebug("CR0 Write\n"); #endif if (handle_cr0_write(info) == -1) { return -1; } - } else if (exit_code == VMEXIT_CR0_READ) { + } + break; + + case VMEXIT_CR0_READ: { #ifdef DEBUG_CTRL_REGS PrintDebug("CR0 Read\n"); #endif if (handle_cr0_read(info) == -1) { return -1; } - } else if (exit_code == VMEXIT_CR3_WRITE) { + } + break; + + case VMEXIT_CR3_WRITE: { #ifdef DEBUG_CTRL_REGS PrintDebug("CR3 Write\n"); #endif if (handle_cr3_write(info) == -1) { return -1; } - } else if (exit_code == VMEXIT_CR3_READ) { + } + break; + + case VMEXIT_CR3_READ: { #ifdef DEBUG_CTRL_REGS PrintDebug("CR3 Read\n"); #endif if (handle_cr3_read(info) == -1) { return -1; } + } + break; - } else if (exit_code == VMEXIT_EXCP14) { + case VMEXIT_EXCP14: { addr_t fault_addr = guest_ctrl->exit_info2; pf_error_t * error_code = (pf_error_t *)&(guest_ctrl->exit_info1); #ifdef DEBUG_SHADOW_PAGING @@ -153,16 +171,20 @@ int handle_svm_exit(struct guest_info * info) { return -1; } } else { - PrintError("Page fault in un implemented paging mode\n"); - return -1; } - } else if (exit_code == VMEXIT_NPF) { + } + break; + + case VMEXIT_NPF: { PrintError("Currently unhandled Nested Page Fault\n"); return -1; + + } + break; - } else if (exit_code == VMEXIT_INVLPG) { + case VMEXIT_INVLPG: { if (info->shdw_pg_mode == SHADOW_PAGING) { #ifdef DEBUG_SHADOW_PAGING PrintDebug("Invlpg\n"); @@ -176,25 +198,40 @@ int handle_svm_exit(struct guest_info * info) { (exit_code == VMEXIT_INVLPGA) || */ - } else if (exit_code == VMEXIT_INTR) { - - // handle_svm_intr(info); + } + break; - } else if (exit_code == VMEXIT_SMI) { + case VMEXIT_INTR: { + + // handle_svm_intr(info); // handled by interrupt dispatch earlier + } + break; + + case VMEXIT_SMI: { + // handle_svm_smi(info); // ignored for now - } else if (exit_code == VMEXIT_HLT) { + } + break; + + case VMEXIT_HLT: { PrintDebug("Guest halted\n"); if (handle_svm_halt(info) == -1) { return -1; } - } else if (exit_code == VMEXIT_PAUSE) { + } + break; + + case VMEXIT_PAUSE: { PrintDebug("Guest paused\n"); if (handle_svm_pause(info) == -1) { return -1; } - } else if (exit_code == VMEXIT_EXCP1) { + } + break; + + case VMEXIT_EXCP1: { #ifdef DEBUG_EMULATOR PrintDebug("DEBUG EXCEPTION\n"); #endif @@ -206,7 +243,10 @@ int handle_svm_exit(struct guest_info * info) { PrintError("VMMCALL with not emulator...\n"); return -1; } - } else if (exit_code == VMEXIT_VMMCALL) { + } + break; + + case VMEXIT_VMMCALL: { #ifdef DEBUG_EMULATOR PrintDebug("VMMCALL\n"); #endif @@ -218,8 +258,686 @@ int handle_svm_exit(struct guest_info * info) { PrintError("VMMCALL with not emulator...\n"); return -1; } + + } + break; - } else { + + case VMEXIT_WBINVD: { +#ifdef DEBUG_EMULATOR + PrintDebug("WBINVD\n"); +#endif + if (!handle_svm_wbinvd(info)) { + return -1; + } + } + break; + + + + /* Exits Following this line are NOT HANDLED */ + /*=======================================================================*/ + + case VMEXIT_CR_READ_MASK: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR_READ_MASK\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR_WRITE_MASK: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR_WRITE_MASK\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR1_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR1_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR1_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR2_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR2_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR2_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR4_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR4_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR4_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR5_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR5_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR5_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR6_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR6_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR6_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR7_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR7_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR7_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR8_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR8_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR8_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR9_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR9_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR9_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR10_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR10_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR10_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR11_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR11_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR11_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR12_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR12_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR12_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR13_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR13_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR13_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR14_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR14_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR14_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR15_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR15_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR15_WRITE\n"); + goto unhandled_exit; + break; + + + case VMEXIT_DR_READ_MASK: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR_READ_MASK\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR_WRITE_MASK: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR_WRITE_MASK\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR0_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR0_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR0_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR1_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR1_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR1_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR2_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR2_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR2_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR3_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR3_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR3_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR4_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR4_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR4_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR5_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR5_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR5_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR6_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR6_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR6_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR7_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR7_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR7_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR8_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR8_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR8_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR9_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR9_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR9_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR10_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR10_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR10_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR11_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR11_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR11_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR12_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR12_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR12_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR13_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR13_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR13_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR14_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR14_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR14_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR15_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_DR15_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_DR15_WRITE\n"); + goto unhandled_exit; + break; + + + case VMEXIT_EXCP_MASK: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP_MASK\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP0: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP0\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP2: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP2\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP3: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP3\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP4: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP4\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP5: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP5\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP6: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP6\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP7: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP7\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP8: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP8\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP9: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP9\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP10: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP10\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP11: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP11\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP12: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP12\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP13: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP13\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP15: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP15\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP16: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP16\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP17: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP17\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP18: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP18\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP19: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP19\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP20: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP20\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP21: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP21\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP22: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP22\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP23: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP23\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP24: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP24\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP25: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP25\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP26: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP26\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP27: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP27\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP28: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP28\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP29: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP29\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP30: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP30\n"); + goto unhandled_exit; + break; + + case VMEXIT_EXCP31: + PrintDebug("Unhandled SVM Exit: VMEXIT_EXCP31\n"); + goto unhandled_exit; + break; + + + case VMEXIT_NMI: + PrintDebug("Unhandled SVM Exit: VMEXIT_NMI\n"); + goto unhandled_exit; + break; + + case VMEXIT_INIT: + PrintDebug("Unhandled SVM Exit: VMEXIT_INIT\n"); + goto unhandled_exit; + break; + + case VMEXIT_VINITR: + PrintDebug("Unhandled SVM Exit: VMEXIT_VINITR\n"); + goto unhandled_exit; + break; + + case VMEXIT_CR0_SEL_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_CR0_SEL_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_IDTR_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_IDTR_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_IDTR_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_GDTR_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_GDTR_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_GDTR_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_LDTR_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_LDTR_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_LDTR_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_TR_READ: + PrintDebug("Unhandled SVM Exit: VMEXIT_TR_READ\n"); + goto unhandled_exit; + break; + + case VMEXIT_TR_WRITE: + PrintDebug("Unhandled SVM Exit: VMEXIT_TR_WRITE\n"); + goto unhandled_exit; + break; + + case VMEXIT_RDTSC: + PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSC\n"); + goto unhandled_exit; + break; + + case VMEXIT_RDPMC: + PrintDebug("Unhandled SVM Exit: VMEXIT_RDPMC\n"); + goto unhandled_exit; + break; + + case VMEXIT_PUSHF: + PrintDebug("Unhandled SVM Exit: VMEXIT_PUSHF\n"); + goto unhandled_exit; + break; + + case VMEXIT_POPF: + PrintDebug("Unhandled SVM Exit: VMEXIT_POPF\n"); + goto unhandled_exit; + break; + + case VMEXIT_CPUID: + PrintDebug("Unhandled SVM Exit: VMEXIT_CPUID\n"); + goto unhandled_exit; + break; + + case VMEXIT_RSM: + PrintDebug("Unhandled SVM Exit: VMEXIT_RSM\n"); + goto unhandled_exit; + break; + + case VMEXIT_IRET: + PrintDebug("Unhandled SVM Exit: VMEXIT_IRET\n"); + goto unhandled_exit; + break; + + case VMEXIT_SWINT: + PrintDebug("Unhandled SVM Exit: VMEXIT_SWINT\n"); + goto unhandled_exit; + break; + + case VMEXIT_INVD: + PrintDebug("Unhandled SVM Exit: VMEXIT_INVD\n"); + goto unhandled_exit; + break; + + case VMEXIT_INVLPGA: + PrintDebug("Unhandled SVM Exit: VMEXIT_INVLPGA\n"); + goto unhandled_exit; + break; + + case VMEXIT_TASK_SWITCH: + PrintDebug("Unhandled SVM Exit: VMEXIT_TASK_SWITCH\n"); + goto unhandled_exit; + break; + + case VMEXIT_FERR_FREEZE: + PrintDebug("Unhandled SVM Exit: VMEXIT_FERR_FREEZE\n"); + goto unhandled_exit; + break; + + case VMEXIT_SHUTDOWN: + PrintDebug("Unhandled SVM Exit: VMEXIT_SHUTDOWN\n"); + goto unhandled_exit; + break; + + case VMEXIT_VMRUN: + PrintDebug("Unhandled SVM Exit: VMEXIT_VMRUN\n"); + goto unhandled_exit; + break; + + + case VMEXIT_STGI: + PrintDebug("Unhandled SVM Exit: VMEXIT_STGI\n"); + goto unhandled_exit; + break; + + case VMEXIT_CLGI: + PrintDebug("Unhandled SVM Exit: VMEXIT_CLGI\n"); + goto unhandled_exit; + break; + + case VMEXIT_SKINIT: + PrintDebug("Unhandled SVM Exit: VMEXIT_SKINIT\n"); + goto unhandled_exit; + break; + + case VMEXIT_RDTSCP: + PrintDebug("Unhandled SVM Exit: VMEXIT_RDTSCP\n"); + goto unhandled_exit; + break; + + case VMEXIT_ICEBP: + PrintDebug("Unhandled SVM Exit: VMEXIT_ICEBP\n"); + goto unhandled_exit; + break; + + case VMEXIT_MONITOR: + PrintDebug("Unhandled SVM Exit: VMEXIT_MONITOR\n"); + goto unhandled_exit; + break; + + case VMEXIT_MWAIT: + PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT\n"); + goto unhandled_exit; + break; + + case VMEXIT_MWAIT_CONDITIONAL: + PrintDebug("Unhandled SVM Exit: VMEXIT_MWAIT_CONDITIONAL\n"); + goto unhandled_exit; + break; + + + case VMEXIT_INVALID_VMCB: + PrintDebug("Unhandled SVM Exit: VMEXIT_INVALID_VMCB\n"); + goto unhandled_exit; + break; + + + unhandled_exit: + + default: { + addr_t rip_addr; char buf[15]; addr_t host_addr; @@ -228,7 +946,6 @@ int handle_svm_exit(struct guest_info * info) { rip_addr = get_addr_linear(info, guest_state->rip, &(info->segments.cs)); - PrintError("SVM Returned:(VMCB=%x)\n", info->vmm_data); PrintError("RIP: %x\n", guest_state->rip); PrintError("RIP Linear: %x\n", rip_addr); @@ -257,9 +974,9 @@ int handle_svm_exit(struct guest_info * info) { PrintError("Invalid memory mode\n"); return -1; } - + PrintError("Host Address of rip = 0x%x\n", host_addr); - + memset(buf, 0, 32); PrintError("Reading instruction stream in guest\n", rip_addr); @@ -269,17 +986,19 @@ int handle_svm_exit(struct guest_info * info) { } else { read_guest_va_memory(info, rip_addr-16, 32, buf); } - + PrintDebug("16 bytes before Rip\n"); PrintTraceMemDump(buf, 16); PrintDebug("Rip onward\n"); PrintTraceMemDump(buf+16, 16); - - - + return -1; } + break; + + } + // END OF SWITCH (EXIT_CODE) // Update the low level state diff --git a/palacios/src/palacios/svm_wbinvd.c b/palacios/src/palacios/svm_wbinvd.c new file mode 100644 index 0000000..06d4dc1 --- /dev/null +++ b/palacios/src/palacios/svm_wbinvd.c @@ -0,0 +1,20 @@ +#include +#include + + +// Writeback and invalidate caches +// should raise #GP if CPL is not zero +// Otherwise execute + +int handle_svm_wbinvd(struct guest_info * info) +{ + if (info->cpl!=0) { + PrintDebug("WBINVD: cpl!=0, injecting GPF\n"); + v3_raise_exception(info,GPF_EXCEPTION); + } else { + info->rip+=2; + asm("wbinvd"); + } + return 0; + +} diff --git a/palacios/src/palacios/vmm_ctrl_regs.c b/palacios/src/palacios/vmm_ctrl_regs.c index 152a7c0..89d896b 100644 --- a/palacios/src/palacios/vmm_ctrl_regs.c +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@ -24,7 +24,7 @@ // force a shadow page table flush // It makes windows loading MUCH faster. // Note that this optimization appears to fail with a 2.6 linux kernel -#define CR3_RELOAD_OPTIMIZATION 0 +#define CR3_RELOAD_OPTIMIZATION 1 @@ -94,7 +94,7 @@ int handle_cr0_write(struct guest_info * info) { struct cr0_32 *real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0); struct cr0_32 *new_cr0= (struct cr0_32 *)(dec_instr.src_operand.operand); - PrintDebug("OperandVal = %x, length=%d\n", *new_cr0, dec_instr_src_operand.size); + PrintDebug("OperandVal = %x, length=%d\n", *new_cr0, dec_instr.src_operand.size); PrintDebug("Old CR0=%x\n", *real_cr0); diff --git a/palacios/src/palacios/vmm_emulator.c b/palacios/src/palacios/vmm_emulator.c index 3fedc51..73a3565 100644 --- a/palacios/src/palacios/vmm_emulator.c +++ b/palacios/src/palacios/vmm_emulator.c @@ -210,14 +210,20 @@ int v3_emulate_memory_write(struct guest_info * info, addr_t write_gva, struct emulated_page * data_page = V3_Malloc(sizeof(struct emulated_page)); addr_t data_addr_offset = PT32_PAGE_OFFSET(write_gva); pte32_t saved_pte; + int i; - PrintDebug("Emulating Write\n"); + PrintDebug("Emulating Write for instruction at 0x%x\n",info->rip); if (info->mem_mode == PHYSICAL_MEM) { ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr); } else { ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr); } + + + PrintDebug("Instruction is"); + for (i=0;i<15;i++) { PrintDebug(" 0x%x",instr[i]); } + PrintDebug("\n"); if (v3_basic_mem_decode(info, (addr_t)instr, &instr_info) == -1) { PrintError("Could not do a basic memory instruction decode\n"); @@ -226,6 +232,10 @@ int v3_emulate_memory_write(struct guest_info * info, addr_t write_gva, return -1; } + if (instr_info.has_rep==1) { + PrintDebug("Emulated instruction has rep\n"); + } + /* if (instr_info.has_rep == 1) { PrintError("We currently don't handle rep* instructions\n");