qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH][SVM] put valid data into exit_int_info if needed
@ 2009-04-20 13:34 Gleb Natapov
  2009-04-22 20:22 ` Anthony Liguori
  0 siblings, 1 reply; 2+ messages in thread
From: Gleb Natapov @ 2009-04-20 13:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: agraf

If fault happened during event delivery exit_int_info should contain
valid info about the event on vm exit.

Signed-off-by: Gleb Natapov <gleb@redhat.com>

diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index be09263..091c724 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -595,6 +595,21 @@ static inline unsigned int get_sp_mask(unsigned int e2)
         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 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
     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 @@ static void do_interrupt64(int intno, int is_int, int error_code,
     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 @@ void do_interrupt_user(int intno, int is_int, int error_code,
         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 @@ void do_interrupt(int intno, int is_int, int error_code,
         }
     }
     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 @@ void do_interrupt(int intno, int is_int, int error_code,
             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 @@ void helper_vmrun(int aflag, int next_eip_addend)
         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 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
     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). */
 
--
			Gleb.

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Qemu-devel] [PATCH][SVM] put valid data into exit_int_info if needed
  2009-04-20 13:34 [Qemu-devel] [PATCH][SVM] put valid data into exit_int_info if needed Gleb Natapov
@ 2009-04-22 20:22 ` Anthony Liguori
  0 siblings, 0 replies; 2+ messages in thread
From: Anthony Liguori @ 2009-04-22 20:22 UTC (permalink / raw)
  To: qemu-devel; +Cc: agraf

Gleb Natapov wrote:
> If fault happened during event delivery exit_int_info should contain
> valid info about the event on vm exit.
>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
>   
Applied.  Thanks.

-- 
Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-04-22 20:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-20 13:34 [Qemu-devel] [PATCH][SVM] put valid data into exit_int_info if needed Gleb Natapov
2009-04-22 20:22 ` Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).