cpu-exec: unify do_interrupt call
Upstream e694d4e289b05d0c9b118850eff961aa9ca33183
Upstream 3c688828bcb3afa2744e1f1729a40eef4a575b56
Upstream d8108fb187bb68459cfe7dca4b5c983db33bcc7b
Change-Id: Ia492dae677ddfe052768b943f8ea275fab8a9c49
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index f3b369a..27fa615 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -21,7 +21,6 @@
#define CPU_NO_GLOBAL_REGS
#include "exec.h"
-#include "exec/exec-all.h"
#include "qemu/host-utils.h"
//#define DEBUG_PCALL
@@ -1157,9 +1156,10 @@
env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
}
+#if defined(CONFIG_USER_ONLY)
/* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
- target_ulong next_eip)
+static void do_interrupt_user(int intno, int is_int, int error_code,
+ target_ulong next_eip)
{
SegmentCache *dt;
target_ulong ptr;
@@ -1188,7 +1188,8 @@
EIP = next_eip;
}
-#if !defined(CONFIG_USER_ONLY)
+#else
+
static void handle_even_inj(int intno, int is_int, int error_code,
int is_hw, int rm)
{
@@ -1214,8 +1215,8 @@
* the int instruction. next_eip is the EIP value AFTER the interrupt
* instruction. It is only relevant if is_int is TRUE.
*/
-void do_interrupt(int intno, int is_int, int error_code,
- target_ulong next_eip, int is_hw)
+static void do_interrupt_all(int intno, int is_int, int error_code,
+ target_ulong next_eip, int is_hw)
{
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1271,12 +1272,52 @@
#if !defined(CONFIG_USER_ONLY)
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);
+ 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);
}
#endif
}
+void do_interrupt(CPUArchState *env1)
+{
+ CPUArchState *saved_env;
+
+ saved_env = env;
+ env = env1;
+#if defined(CONFIG_USER_ONLY)
+ /* if user mode only, we simulate a fake exception
+ which will be handled outside the cpu execution
+ loop */
+ do_interrupt_user(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip);
+ /* successfully delivered */
+ env->old_exception = -1;
+#else
+ /* simulate a real cpu exception. On i386, it can
+ trigger new exceptions, but we do not handle
+ double or triple faults yet. */
+ do_interrupt_all(env->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip, 0);
+ /* successfully delivered */
+ env->old_exception = -1;
+#endif
+ env = saved_env;
+}
+
+void do_interrupt_x86_hardirq(CPUArchState *env1, int intno, int is_hw)
+{
+ CPUArchState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ do_interrupt_all(intno, 0, 0, 0, is_hw);
+ env = saved_env;
+}
+
/* This should come from sysemu.h - if we could include it here... */
void qemu_system_reset_request(void);
@@ -1361,7 +1402,7 @@
#if defined(CONFIG_USER_ONLY)
-void do_smm_enter(void)
+void do_smm_enter(CPUArchState *env1)
{
}
@@ -1377,11 +1418,15 @@
#define SMM_REVISION_ID 0x00020000
#endif
-void do_smm_enter(void)
+void do_smm_enter(CPUArchState *env1)
{
target_ulong sm_state;
SegmentCache *dt;
int i, offset;
+ CPUArchState *saved_env;
+
+ saved_env = env;
+ env = env1;
qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
@@ -1508,6 +1553,7 @@
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
CC_OP = CC_OP_EFLAGS;
+ env = saved_env;
}
void helper_rsm(void)
@@ -4845,6 +4891,10 @@
{
}
+void svm_check_intercept(CPUArchState *env1, uint32_t type)
+{
+}
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
@@ -5026,7 +5076,7 @@
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
/* XXX: is it always correct ? */
- do_interrupt(vector, 0, 0, 0, 1);
+ do_interrupt_all(vector, 0, 0, 0, 1);
break;
case SVM_EVTINJ_TYPE_NMI:
env->exception_index = EXCP02_NMI;
@@ -5235,6 +5285,17 @@
}
}
+void svm_check_intercept(CPUArchState *env1, uint32_t type)
+{
+ CPUArchState *saved_env;
+
+ saved_env = env;
+ env = env1;
+ helper_svm_check_intercept_param(type, 0);
+ env = saved_env;
+}
+
+
void helper_svm_check_io(uint32_t port, uint32_t param,
uint32_t next_eip_addend)
{
@@ -5548,6 +5609,18 @@
}
}
+uint32_t cpu_cc_compute_all(CPUArchState *env1, int op)
+{
+ CPUArchState *saved_env;
+ uint32_t ret;
+
+ saved_env = env;
+ env = env1;
+ ret = helper_cc_compute_all(op);
+ env = saved_env;
+ return ret;
+}
+
uint32_t helper_cc_compute_c(int op)
{
switch (op) {