X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_ctrl_regs.c;h=3616ae8a9b4ab972dd7584b3087ebcde8780fc71;hb=93a8c8c46dc39c3994a8eec0076c28eb14a77da1;hp=4c84e2edde63100e63fec866fa342f34cfb17b01;hpb=840d15c3a300636e758fcfcf403ae415ffa67816;p=palacios-OLD.git diff --git a/palacios/src/palacios/vmm_ctrl_regs.c b/palacios/src/palacios/vmm_ctrl_regs.c index 4c84e2e..3616ae8 100644 --- a/palacios/src/palacios/vmm_ctrl_regs.c +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@ -557,103 +557,40 @@ int v3_handle_efer_read(struct guest_info * core, uint_t msr, struct v3_msr * ds } - -// TODO: this is a disaster we need to clean this up... int v3_handle_efer_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { - //struct efer_64 * new_efer = (struct efer_64 *)&(src.value); - struct efer_64 * shadow_efer = (struct efer_64 *)&(core->ctrl_regs.efer); - struct v3_msr * guest_efer = &(core->shdw_pg_state.guest_efer); - - PrintDebug("EFER Write\n"); - PrintDebug("EFER Write Values: HI=%x LO=%x\n", src.hi, src.lo); - - //PrintDebug("Old EFER=%p\n", (void *)*(addr_t*)(shadow_efer)); - - // We virtualize the guests efer to hide the SVME and LMA bits - guest_efer->value = src.value; - - if (core->shdw_pg_mode == SHADOW_PAGING) { - // Enable/Disable Syscall - shadow_efer->sce = src.value & 0x1; - } else if (core->shdw_pg_mode == NESTED_PAGING) { - *(uint64_t *)shadow_efer = src.value; - shadow_efer->svme = 1; - } - return 0; -} - - -/* KCH: all of the star handlers are for syscall interposition */ -int v3_handle_star_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { - -#ifdef CONFIG_DEBUG_SYSCALL_HIJACK - PrintDebug("STAR Read\n"); -#endif - - return 0; -} - - -int v3_handle_star_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { - -#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK - PrintDebug("STAR Write\n"); -#endif - return 0; -} - - -int v3_handle_lstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { - -#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK - PrintDebug("LSTAR Read\n"); -#endif - return 0; -} - - -int v3_handle_lstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { + struct v3_msr * vm_efer = &(core->shdw_pg_state.guest_efer); + struct efer_64 * hw_efer = (struct efer_64 *)&(core->ctrl_regs.efer); + struct efer_64 old_hw_efer = *((struct efer_64 *)&core->ctrl_regs.efer); -#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK - ulong_t entry = ((ulong_t)src.hi << 32) | (ulong_t)src.lo; - PrintDebug("LSTAR Write\n"); - PrintDebug("\tKernel syscall entry point: 0x%lx\n", entry); -#endif - - return 0; -} - - -int v3_handle_cstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { + PrintDebug("EFER Write HI=%x LO=%x\n", src.hi, src.lo); -#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK - PrintDebug("CSTAR Read\n"); -#endif - return 0; -} + // Set EFER value seen by guest if it reads EFER + vm_efer->value = src.value; + // Set EFER value seen by hardware while the guest is running + *(uint64_t *)hw_efer = src.value; -int v3_handle_cstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { - -#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK - PrintDebug("CSTAR Write\n"); -#endif - return 0; -} + // Catch unsupported features + if ((old_hw_efer.lme == 1) && (hw_efer->lme == 0)) { + PrintError("Disabling long mode once it has been enabled is not supported\n"); + return -1; + } -int v3_handle_seeip_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { - /* we don't care about reads */ - return 0; -} + // Set LME and LMA bits seen by hardware + if (old_hw_efer.lme == 0) { + // Long mode was not previously enabled, so the lme bit cannot + // be set yet. It will be set later when the guest sets CR0.PG + // to enable paging. + hw_efer->lme = 0; + } else { + // Long mode was previously enabled. Ensure LMA bit is set. + // VMX does not automatically set LMA, and this should not affect SVM. + hw_efer->lma = 1; + } -int v3_handle_seeip_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { -#ifdef V3_CONFIG_DEBUG_SYSALL_HIJACK - PrintDebug("SYSENTER_EIP Write\n"); -#endif return 0; } - int v3_handle_vm_cr_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { /* tell the guest that the BIOS disabled SVM, that way it doesn't get * confused by the fact that CPUID reports SVM as available but it still