[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [7230] put valid data into exit_int_info if needed (Gleb Na
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] [7230] put valid data into exit_int_info if needed (Gleb Natapov) |
Date: |
Wed, 22 Apr 2009 20:20:09 +0000 |
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 <address@hidden>
Signed-off-by: Anthony Liguori <address@hidden>
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). */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [7230] put valid data into exit_int_info if needed (Gleb Natapov),
Anthony Liguori <=