From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lwivc-0004EE-TV for qemu-devel@nongnu.org; Wed, 22 Apr 2009 16:20:21 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lwivc-0004Do-7X for qemu-devel@nongnu.org; Wed, 22 Apr 2009 16:20:20 -0400 Received: from [199.232.76.173] (port=52919 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lwivb-0004Dk-T9 for qemu-devel@nongnu.org; Wed, 22 Apr 2009 16:20:19 -0400 Received: from savannah.gnu.org ([199.232.41.3]:39483 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Lwivb-0008IA-LZ for qemu-devel@nongnu.org; Wed, 22 Apr 2009 16:20:19 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Lwiva-0007va-8h for qemu-devel@nongnu.org; Wed, 22 Apr 2009 20:20:18 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.69) (envelope-from ) id 1LwivR-0007rv-8n for qemu-devel@nongnu.org; Wed, 22 Apr 2009 20:20:11 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Wed, 22 Apr 2009 20:20:09 +0000 Subject: [Qemu-devel] [7230] put valid data into exit_int_info if needed (Gleb Natapov) List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 7230 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7230 Author: aliguori Date: 2009-04-22 20:20:07 +0000 (Wed, 22 Apr 2009) Log Message: ----------- put valid data into exit_int_info if needed (Gleb Natapov) If fault happened during event delivery exit_int_info should contain valid info about the event on vm exit. Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/target-i386/op_helper.c Modified: trunk/target-i386/op_helper.c =================================================================== --- trunk/target-i386/op_helper.c 2009-04-22 20:20:00 UTC (rev 7229) +++ trunk/target-i386/op_helper.c 2009-04-22 20:20:07 UTC (rev 7230) @@ -595,6 +595,21 @@ return 0xffff; } +static int exeption_has_error_code(int intno) +{ + switch(intno) { + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 17: + return 1; + } + return 0; +} + #ifdef TARGET_X86_64 #define SET_ESP(val, sp_mask)\ do {\ @@ -650,19 +665,8 @@ uint32_t old_eip, sp_mask; has_error_code = 0; - if (!is_int && !is_hw) { - switch(intno) { - case 8: - case 10: - case 11: - case 12: - case 13: - case 14: - case 17: - has_error_code = 1; - break; - } - } + if (!is_int && !is_hw) + has_error_code = exeption_has_error_code(intno); if (is_int) old_eip = next_eip; else @@ -886,19 +890,8 @@ target_ulong old_eip, esp, offset; has_error_code = 0; - if (!is_int && !is_hw) { - switch(intno) { - case 8: - case 10: - case 11: - case 12: - case 13: - case 14: - case 17: - has_error_code = 1; - break; - } - } + if (!is_int && !is_hw) + has_error_code = exeption_has_error_code(intno); if (is_int) old_eip = next_eip; else @@ -1198,6 +1191,25 @@ EIP = next_eip; } +static void handle_even_inj(int intno, int is_int, int error_code, + int is_hw, int rm) +{ + uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); + if (!(event_inj & SVM_EVTINJ_VALID)) { + int type; + if (is_int) + type = SVM_EVTINJ_TYPE_SOFT; + else + type = SVM_EVTINJ_TYPE_EXEPT; + event_inj = intno | type | SVM_EVTINJ_VALID; + if (!rm && exeption_has_error_code(intno)) { + event_inj |= SVM_EVTINJ_VALID_ERR; + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err), error_code); + } + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj); + } +} + /* * Begin execution of an interruption. is_int is TRUE if coming from * the int instruction. next_eip is the EIP value AFTER the interrupt @@ -1238,6 +1250,8 @@ } } if (env->cr[0] & CR0_PE_MASK) { + if (env->hflags & HF_SVMI_MASK) + handle_even_inj(intno, is_int, error_code, is_hw, 0); #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { do_interrupt64(intno, is_int, error_code, next_eip, is_hw); @@ -1247,8 +1261,15 @@ do_interrupt_protected(intno, is_int, error_code, next_eip, is_hw); } } else { + if (env->hflags & HF_SVMI_MASK) + handle_even_inj(intno, is_int, error_code, is_hw, 1); do_interrupt_real(intno, is_int, error_code, next_eip); } + + if (env->hflags & HF_SVMI_MASK) { + uint32_t event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj)); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID); + } } /* This should come from sysemu.h - if we could include it here... */ @@ -4994,7 +5015,6 @@ uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK; uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR; uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err)); - stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Injecting(%#hx): ", valid_err); /* FIXME: need to implement valid_err */ @@ -5332,6 +5352,11 @@ stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_code), exit_code); stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_1), exit_info_1); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info), + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj))); + stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_int_info_err), + ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err))); + env->hflags2 &= ~HF2_GIF_MASK; /* FIXME: Resets the current ASID register to zero (host ASID). */