aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2012-04-28 19:35:10 +0000
committerBlue Swirl <blauwirbel@gmail.com>2012-06-28 20:28:08 +0000
commit77b2bc2c096be44a36c45d777abb81a298c05c98 (patch)
tree6b102bf6993d28825d37938b3c26939c3ef33b7d
parent20054ef03e0bd051178edd9d1378aa59570dbcf5 (diff)
x86: avoid AREG0 for exceptions
Add an explicit CPUX86State parameter instead of relying on AREG0. Merge raise_exception_env() to raise_exception(), likewise with raise_exception_err_env() and raise_exception_err(). Introduce cpu_svm_check_intercept_param() and cpu_vmexit() as wrappers. Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r--cpu-exec.c12
-rw-r--r--target-i386/cpu.h10
-rw-r--r--target-i386/helper.c4
-rw-r--r--target-i386/helper.h4
-rw-r--r--target-i386/op_helper.c418
-rw-r--r--target-i386/translate.c4
-rw-r--r--user-exec.c2
7 files changed, 234 insertions, 220 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index 624c409f7b..08c35f72d4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -289,7 +289,8 @@ int cpu_exec(CPUArchState *env)
#endif
#if defined(TARGET_I386)
if (interrupt_request & CPU_INTERRUPT_INIT) {
- svm_check_intercept(env, SVM_EXIT_INIT);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
+ 0);
do_cpu_init(x86_env_get_cpu(env));
env->exception_index = EXCP_HALTED;
cpu_loop_exit(env);
@@ -298,7 +299,8 @@ int cpu_exec(CPUArchState *env)
} else if (env->hflags2 & HF2_GIF_MASK) {
if ((interrupt_request & CPU_INTERRUPT_SMI) &&
!(env->hflags & HF_SMM_MASK)) {
- svm_check_intercept(env, SVM_EXIT_SMI);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
+ 0);
env->interrupt_request &= ~CPU_INTERRUPT_SMI;
do_smm_enter(env);
next_tb = 0;
@@ -319,7 +321,8 @@ int cpu_exec(CPUArchState *env)
(env->eflags & IF_MASK &&
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
int intno;
- svm_check_intercept(env, SVM_EXIT_INTR);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
+ 0);
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
@@ -333,7 +336,8 @@ int cpu_exec(CPUArchState *env)
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
int intno;
/* FIXME: this should respect TPR */
- svm_check_intercept(env, SVM_EXIT_VINTR);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
+ 0);
intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index bcf663eeb5..c546723eea 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1074,13 +1074,15 @@ void cpu_x86_inject_mce(Monitor *mon, CPUX86State *cenv, int bank,
/* op_helper.c */
void do_interrupt(CPUX86State *env);
void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
-void QEMU_NORETURN raise_exception_env(int exception_index, CPUX86State *nenv);
-void QEMU_NORETURN raise_exception_err_env(CPUX86State *nenv, int exception_index,
- int error_code);
+void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index);
+void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index,
+ int error_code);
void do_smm_enter(CPUX86State *env1);
-void svm_check_intercept(CPUX86State *env1, uint32_t type);
+void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
+ uint64_t param);
+void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 2cc80977e8..d3af6eaf71 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -951,7 +951,7 @@ static void breakpoint_handler(CPUX86State *env)
if (env->watchpoint_hit->flags & BP_CPU) {
env->watchpoint_hit = NULL;
if (check_hw_breakpoints(env, 0))
- raise_exception_env(EXCP01_DB, env);
+ raise_exception(env, EXCP01_DB);
else
cpu_resume_from_signal(env, NULL);
}
@@ -960,7 +960,7 @@ static void breakpoint_handler(CPUX86State *env)
if (bp->pc == env->eip) {
if (bp->flags & BP_CPU) {
check_hw_breakpoints(env, 1);
- raise_exception_env(EXCP01_DB, env);
+ raise_exception(env, EXCP01_DB);
}
break;
}
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 761954e925..99ca18396d 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -63,8 +63,8 @@ DEF_HELPER_1(monitor, void, tl)
DEF_HELPER_1(mwait, void, int)
DEF_HELPER_0(debug, void)
DEF_HELPER_0(reset_rf, void)
-DEF_HELPER_2(raise_interrupt, void, int, int)
-DEF_HELPER_1(raise_exception, void, int)
+DEF_HELPER_3(raise_interrupt, void, env, int, int)
+DEF_HELPER_2(raise_exception, void, env, int)
DEF_HELPER_0(cli, void)
DEF_HELPER_0(sti, void)
DEF_HELPER_0(set_inhibit_irq, void)
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index b9c1b9335b..773148cd3d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -139,16 +139,13 @@ static inline void cpu_load_efer(CPUX86State *env, uint64_t val)
}
#if 0
-#define raise_exception_err(a, b) \
+#define raise_exception_err(env, a, b) \
do { \
qemu_log("raise_exception line=%d\n", __LINE__); \
- (raise_exception_err)(a, b); \
+ (raise_exception_err)(env, a, b); \
} while (0)
#endif
-static void QEMU_NORETURN raise_exception_err(int exception_index,
- int error_code);
-
static const uint8_t parity_table[256] = {
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
@@ -317,7 +314,7 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr,
shift = type >> 3;
index = (dpl * 4 + 2) << shift;
if (index + (4 << shift) - 1 > env->tr.limit) {
- raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc);
}
if (shift == 0) {
*esp_ptr = lduw_kernel(env->tr.base + index);
@@ -336,47 +333,47 @@ static void tss_load_seg(int seg_reg, int selector)
if ((selector & 0xfffc) != 0) {
if (load_segment(&e1, &e2, selector) != 0) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK)) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
if (seg_reg == R_CS) {
if (!(e2 & DESC_CS_MASK)) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
/* XXX: is it correct? */
if (dpl != rpl) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
if ((e2 & DESC_C_MASK) && dpl > rpl) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
} else if (seg_reg == R_SS) {
/* SS must be writable data */
if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
if (dpl != cpl || dpl != rpl) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
} else {
/* not readable code */
if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
/* if data or non conforming code, checks the rights */
if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) {
if (dpl < cpl || dpl < rpl) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
}
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
cpu_x86_load_seg_cache(env, seg_reg, selector,
get_seg_base(e1, e2),
@@ -384,7 +381,7 @@ static void tss_load_seg(int seg_reg, int selector)
e2);
} else {
if (seg_reg == R_SS || seg_reg == R_CS) {
- raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);
}
}
}
@@ -414,26 +411,26 @@ static void switch_tss(int tss_selector,
/* if task gate, we read the TSS segment and we load it */
if (type == 5) {
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc);
}
tss_selector = e1 >> 16;
if (tss_selector & 4) {
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
if (load_segment(&e1, &e2, tss_selector) != 0) {
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);
}
if (e2 & DESC_S_MASK) {
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);
}
type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
if ((type & 7) != 1) {
- raise_exception_err(EXCP0D_GPF, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);
}
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc);
}
if (type & 8) {
@@ -445,7 +442,7 @@ static void switch_tss(int tss_selector,
tss_base = get_seg_base(e1, e2);
if ((tss_selector & 4) != 0 ||
tss_limit < tss_limit_max) {
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;
if (old_type & 8) {
@@ -619,23 +616,23 @@ static void switch_tss(int tss_selector,
/* load the LDT */
if (new_ldt & 4) {
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
if ((new_ldt & 0xfffc) != 0) {
dt = &env->gdt;
index = new_ldt & ~7;
if ((index + 7) > dt->limit) {
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
ptr = dt->base + index;
e1 = ldl_kernel(ptr);
e2 = ldl_kernel(ptr + 4);
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) {
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0A_TSS, new_ldt & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);
}
load_seg_cache_raw_dt(&env->ldt, e1, e2);
}
@@ -653,7 +650,7 @@ static void switch_tss(int tss_selector,
/* check that EIP is in the CS segment limits */
if (new_eip > env->segs[R_CS].limit) {
/* XXX: different exception if CALL? */
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
#ifndef CONFIG_USER_ONLY
@@ -692,7 +689,7 @@ static inline void check_io(int addr, int size)
/* all bits must be zero to allow the I/O */
if ((val & mask) != 0) {
fail:
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
}
@@ -835,7 +832,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
dt = &env->idt;
if (intno * 8 + 7 > dt->limit) {
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
ptr = dt->base + intno * 8;
e1 = ldl_kernel(ptr);
@@ -846,7 +843,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
case 5: /* task gate */
/* must do that check here to return the correct error code */
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
+ raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
}
switch_tss(intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip);
if (has_error_code) {
@@ -877,60 +874,60 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
case 15: /* 386 trap gate */
break;
default:
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
break;
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
/* check privilege if software int */
if (is_int && dpl < cpl) {
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
/* check valid bit */
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
+ raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);
}
selector = e1 >> 16;
offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
if ((selector & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
if (load_segment(&e1, &e2, selector) != 0) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (dpl > cpl) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
/* to inner privilege */
get_ss_esp_from_tss(&ss, &esp, dpl);
if ((ss & 0xfffc) == 0) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if ((ss & 3) != dpl) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (load_segment(&ss_e1, &ss_e2, ss) != 0) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
if (ss_dpl != dpl) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (!(ss_e2 & DESC_S_MASK) ||
(ss_e2 & DESC_CS_MASK) ||
!(ss_e2 & DESC_W_MASK)) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (!(ss_e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
new_stack = 1;
sp_mask = get_sp_mask(ss_e2);
@@ -938,7 +935,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
/* to same privilege */
if (env->eflags & VM_MASK) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
new_stack = 0;
sp_mask = get_sp_mask(env->segs[R_SS].flags);
@@ -946,7 +943,7 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
esp = ESP;
dpl = cpl;
} else {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
new_stack = 0; /* avoid warning */
sp_mask = 0; /* avoid warning */
ssp = 0; /* avoid warning */
@@ -1055,7 +1052,7 @@ static inline target_ulong get_rsp_from_tss(int level)
}
index = 8 * level + 4;
if ((index + 7) > env->tr.limit) {
- raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, env->tr.selector & 0xfffc);
}
return ldq_kernel(env->tr.base + index);
}
@@ -1083,7 +1080,7 @@ static void do_interrupt64(int intno, int is_int, int error_code,
dt = &env->idt;
if (intno * 16 + 15 > dt->limit) {
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
}
ptr = dt->base + intno * 16;
e1 = ldl_kernel(ptr);
@@ -1096,41 +1093,41 @@ static void do_interrupt64(int intno, int is_int, int error_code,
case 15: /* 386 trap gate */
break;
default:
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
break;
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
cpl = env->hflags & HF_CPL_MASK;
/* check privilege if software int */
if (is_int && dpl < cpl) {
- raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 16 + 2);
}
/* check valid bit */
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2);
+ raise_exception_err(env, EXCP0B_NOSEG, intno * 16 + 2);
}
selector = e1 >> 16;
offset = ((target_ulong)e3 << 32) | (e2 & 0xffff0000) | (e1 & 0x0000ffff);
ist = e2 & 7;
if ((selector & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
if (load_segment(&e1, &e2, selector) != 0) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (dpl > cpl) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
/* to inner privilege */
@@ -1145,7 +1142,7 @@ static void do_interrupt64(int intno, int is_int, int error_code,
} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
/* to same privilege */
if (env->eflags & VM_MASK) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
new_stack = 0;
if (ist != 0) {
@@ -1156,7 +1153,7 @@ static void do_interrupt64(int intno, int is_int, int error_code,
esp &= ~0xfLL; /* align stack */
dpl = cpl;
} else {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
new_stack = 0; /* avoid warning */
esp = 0; /* avoid warning */
}
@@ -1206,7 +1203,7 @@ void helper_syscall(int next_eip_addend)
int selector;
if (!(env->efer & MSR_EFER_SCE)) {
- raise_exception_err(EXCP06_ILLOP, 0);
+ raise_exception_err(env, EXCP06_ILLOP, 0);
}
selector = (env->star >> 32) & 0xffff;
if (env->hflags & HF_LMA_MASK) {
@@ -1263,11 +1260,11 @@ void helper_sysret(int dflag)
int cpl, selector;
if (!(env->efer & MSR_EFER_SCE)) {
- raise_exception_err(EXCP06_ILLOP, 0);
+ raise_exception_err(env, EXCP06_ILLOP, 0);
}
cpl = env->hflags & HF_CPL_MASK;
if (!(env->cr[0] & CR0_PE_MASK) || cpl != 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
selector = (env->star >> 48) & 0xffff;
if (env->hflags & HF_LMA_MASK) {
@@ -1326,7 +1323,7 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
/* real mode (simpler!) */
dt = &env->idt;
if (intno * 4 + 3 > dt->limit) {
- raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+ raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2);
}
ptr = dt->base + intno * 4;
offset = lduw_kernel(ptr);
@@ -1375,7 +1372,7 @@ static void do_interrupt_user(int intno, int is_int, int error_code,
cpl = env->hflags & HF_CPL_MASK;
/* check privilege if software int */
if (is_int && dpl < cpl) {
- raise_exception_err(EXCP0D_GPF, (intno << shift) + 2);
+ raise_exception_err(env, EXCP0D_GPF, (intno << shift) + 2);
}
/* Since we emulate only user space, we cannot do more than
@@ -1540,7 +1537,7 @@ void qemu_system_reset_request(void);
* needed. It should only be called, if this is not an interrupt.
* Returns the new exception number.
*/
-static int check_exception(int intno, int *error_code)
+static int check_exception(CPUX86State *env, int intno, int *error_code)
{
int first_contributory = env->old_exception == 0 ||
(env->old_exception >= 10 &&
@@ -1554,7 +1551,7 @@ static int check_exception(int intno, int *error_code)
#if !defined(CONFIG_USER_ONLY)
if (env->old_exception == EXCP08_DBLE) {
if (env->hflags & HF_SVMI_MASK) {
- helper_vmexit(SVM_EXIT_SHUTDOWN, 0); /* does not return */
+ cpu_vmexit(env, SVM_EXIT_SHUTDOWN, 0); /* does not return */
}
qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
@@ -1585,15 +1582,16 @@ static int check_exception(int intno, int *error_code)
* EIP value AFTER the interrupt instruction. It is only relevant if
* is_int is TRUE.
*/
-static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
- int next_eip_addend)
+static void QEMU_NORETURN raise_interrupt2(CPUX86State *env, int intno,
+ int is_int, int error_code,
+ int next_eip_addend)
{
if (!is_int) {
- helper_svm_check_intercept_param(SVM_EXIT_EXCP_BASE + intno,
- error_code);
- intno = check_exception(intno, &error_code);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
+ error_code);
+ intno = check_exception(env, intno, &error_code);
} else {
- helper_svm_check_intercept_param(SVM_EXIT_SWINT, 0);
+ cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0);
}
env->exception_index = intno;
@@ -1605,28 +1603,26 @@ static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
/* shortcuts to generate exceptions */
-static void QEMU_NORETURN raise_exception_err(int exception_index,
- int error_code)
-{
- raise_interrupt(exception_index, 0, error_code, 0);
-}
-
-void raise_exception_err_env(CPUX86State *nenv, int exception_index,
- int error_code)
+static void QEMU_NORETURN raise_interrupt(CPUX86State *nenv,
+ int intno, int is_int,
+ int error_code,
+ int next_eip_addend)
{
env = nenv;
- raise_interrupt(exception_index, 0, error_code, 0);
+ raise_interrupt2(env, intno, is_int, error_code, next_eip_addend);
}
-static void QEMU_NORETURN raise_exception(int exception_index)
+void raise_exception_err(CPUX86State *nenv, int exception_index,
+ int error_code)
{
- raise_interrupt(exception_index, 0, 0, 0);
+ env = nenv;
+ raise_interrupt2(env, exception_index, 0, error_code, 0);
}
-void raise_exception_env(int exception_index, CPUX86State *nenv)
+void raise_exception(CPUX86State *nenv, int exception_index)
{
env = nenv;
- raise_exception(exception_index);
+ raise_interrupt2(env, exception_index, 0, 0, 0);
}
/* SMM support */
@@ -1922,11 +1918,11 @@ void helper_divb_AL(target_ulong t0)
num = (EAX & 0xffff);
den = (t0 & 0xff);
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
if (q > 0xff) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q &= 0xff;
r = (num % den) & 0xff;
@@ -1940,11 +1936,11 @@ void helper_idivb_AL(target_ulong t0)
num = (int16_t)EAX;
den = (int8_t)t0;
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
if (q != (int8_t)q) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q &= 0xff;
r = (num % den) & 0xff;
@@ -1958,11 +1954,11 @@ void helper_divw_AX(target_ulong t0)
num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
den = (t0 & 0xffff);
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
if (q > 0xffff) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q &= 0xffff;
r = (num % den) & 0xffff;
@@ -1977,11 +1973,11 @@ void helper_idivw_AX(target_ulong t0)
num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
den = (int16_t)t0;
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
if (q != (int16_t)q) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q &= 0xffff;
r = (num % den) & 0xffff;
@@ -1997,12 +1993,12 @@ void helper_divl_EAX(target_ulong t0)
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
den = t0;
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
r = (num % den);
if (q > 0xffffffff) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
EAX = (uint32_t)q;
EDX = (uint32_t)r;
@@ -2016,12 +2012,12 @@ void helper_idivl_EAX(target_ulong t0)
num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
den = t0;
if (den == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
q = (num / den);
r = (num % den);
if (q != (int32_t)q) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
EAX = (uint32_t)q;
EDX = (uint32_t)r;
@@ -2164,7 +2160,7 @@ void helper_into(int next_eip_addend)
eflags = helper_cc_compute_all(CC_OP);
if (eflags & CC_O) {
- raise_interrupt(EXCP04_INTO, 1, 0, next_eip_addend);
+ raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend);
}
}
@@ -2195,7 +2191,7 @@ void helper_cmpxchg16b(target_ulong a0)
int eflags;
if ((a0 & 0xf) != 0) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
eflags = helper_cc_compute_all(CC_OP);
d0 = ldq(a0);
@@ -2222,7 +2218,7 @@ void helper_single_step(void)
check_hw_breakpoints(env, 1);
env->dr[6] |= DR6_BS;
#endif
- raise_exception(EXCP01_DB);
+ raise_exception(env, EXCP01_DB);
}
void helper_cpuid(void)
@@ -2316,7 +2312,7 @@ void helper_lldt(int selector)
env->ldt.limit = 0;
} else {
if (selector & 0x4) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
dt = &env->gdt;
index = selector & ~7;
@@ -2329,16 +2325,16 @@ void helper_lldt(int selector)
entry_limit = 7;
}
if ((index + entry_limit) > dt->limit) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
e1 = ldl_kernel(ptr);
e2 = ldl_kernel(ptr + 4);
if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
@@ -2371,7 +2367,7 @@ void helper_ltr(int selector)
env->tr.flags = 0;
} else {
if (selector & 0x4) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
dt = &env->gdt;
index = selector & ~7;
@@ -2384,7 +2380,7 @@ void helper_ltr(int selector)
entry_limit = 7;
}
if ((index + entry_limit) > dt->limit) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
e1 = ldl_kernel(ptr);
@@ -2392,10 +2388,10 @@ void helper_ltr(int selector)
type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
if ((e2 & DESC_S_MASK) ||
(type != 1 && type != 9)) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
@@ -2404,7 +2400,7 @@ void helper_ltr(int selector)
e3 = ldl_kernel(ptr + 8);
e4 = ldl_kernel(ptr + 12);
if ((e4 >> DESC_TYPE_SHIFT) & 0xf) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
load_seg_cache_raw_dt(&env->tr, e1, e2);
env->tr.base |= (target_ulong)e3 << 32;
@@ -2437,7 +2433,7 @@ void helper_load_seg(int seg_reg, int selector)
&& (!(env->hflags & HF_CS64_MASK) || cpl == 3)
#endif
) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
} else {
@@ -2449,44 +2445,44 @@ void helper_load_seg(int seg_reg, int selector)
}
index = selector & ~7;
if ((index + 7) > dt->limit) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
ptr = dt->base + index;
e1 = ldl_kernel(ptr);
e2 = ldl_kernel(ptr + 4);
if (!(e2 & DESC_S_MASK)) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
rpl = selector & 3;
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (seg_reg == R_SS) {
/* must be writable segment */
if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (rpl != cpl || dpl != cpl) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
} else {
/* must be readable segment */
if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {
/* if not conforming code, test rights */
if (dpl < cpl || dpl < rpl) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
}
}
if (!(e2 & DESC_P_MASK)) {
if (seg_reg == R_SS) {
- raise_exception_err(EXCP0C_STACK, selector & 0xfffc);
+ raise_exception_err(env, EXCP0C_STACK, selector & 0xfffc);
} else {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
}
@@ -2516,39 +2512,39 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
target_ulong next_eip;
if ((new_cs & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
if (load_segment(&e1, &e2, new_cs) != 0) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpl = env->hflags & HF_CPL_MASK;
if (e2 & DESC_S_MASK) {
if (!(e2 & DESC_CS_MASK)) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (e2 & DESC_C_MASK) {
/* conforming code segment */
if (dpl > cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
} else {
/* non conforming code segment */
rpl = new_cs & 3;
if (rpl > cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (dpl != cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);
}
limit = get_seg_limit(e1, e2);
if (new_eip > limit &&
!(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK)) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
get_seg_base(e1, e2), limit, e2);
@@ -2564,7 +2560,7 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
case 9: /* 386 TSS */
case 5: /* task gate */
if (dpl < cpl || dpl < rpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
next_eip = env->eip + next_eip_addend;
switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
@@ -2573,10 +2569,10 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
case 4: /* 286 call gate */
case 12: /* 386 call gate */
if ((dpl < cpl) || (dpl < rpl)) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);
}
gate_cs = e1 >> 16;
new_eip = (e1 & 0xffff);
@@ -2584,31 +2580,31 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
new_eip |= (e2 & 0xffff0000);
}
if (load_segment(&e1, &e2, gate_cs) != 0) {
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
/* must be code segment */
if (((e2 & (DESC_S_MASK | DESC_CS_MASK)) !=
(DESC_S_MASK | DESC_CS_MASK))) {
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc);
}
if (((e2 & DESC_C_MASK) && (dpl > cpl)) ||
(!(e2 & DESC_C_MASK) && (dpl != cpl))) {
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0D_GPF, gate_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, gate_cs & 0xfffc);
}
limit = get_seg_limit(e1, e2);
if (new_eip > limit) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
cpu_x86_load_seg_cache(env, R_CS, (gate_cs & 0xfffc) | cpl,
get_seg_base(e1, e2), limit, e2);
EIP = new_eip;
break;
default:
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
break;
}
}
@@ -2654,35 +2650,35 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);
LOG_PCALL_STATE(env);
if ((new_cs & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
if (load_segment(&e1, &e2, new_cs) != 0) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpl = env->hflags & HF_CPL_MASK;
LOG_PCALL("desc=%08x:%08x\n", e1, e2);
if (e2 & DESC_S_MASK) {
if (!(e2 & DESC_CS_MASK)) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (e2 & DESC_C_MASK) {
/* conforming code segment */
if (dpl > cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
} else {
/* non conforming code segment */
rpl = new_cs & 3;
if (rpl > cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (dpl != cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);
}
#ifdef TARGET_X86_64
@@ -2716,7 +2712,7 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
limit = get_seg_limit(e1, e2);
if (new_eip > limit) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
/* from this point, not restartable */
SET_ESP(sp, sp_mask);
@@ -2734,7 +2730,7 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
case 9: /* available 386 TSS */
case 5: /* task gate */
if (dpl < cpl || dpl < rpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
switch_tss(new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);
CC_OP = CC_OP_EFLAGS;
@@ -2743,37 +2739,37 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
case 12: /* 386 call gate */
break;
default:
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
break;
}
shift = type >> 3;
if (dpl < cpl || dpl < rpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
/* check valid bit */
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);
}
selector = e1 >> 16;
offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);
param_count = e2 & 0x1f;
if ((selector & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
if (load_segment(&e1, &e2, selector) != 0) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (dpl > cpl) {
- raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
}
if (!(e2 & DESC_C_MASK) && dpl < cpl) {
@@ -2783,25 +2779,25 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
"\n",
ss, sp, param_count, ESP);
if ((ss & 0xfffc) == 0) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if ((ss & 3) != dpl) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (load_segment(&ss_e1, &ss_e2, ss) != 0) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
if (ss_dpl != dpl) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (!(ss_e2 & DESC_S_MASK) ||
(ss_e2 & DESC_CS_MASK) ||
!(ss_e2 & DESC_W_MASK)) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
if (!(ss_e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);
}
/* push_size = ((param_count * 2) + 8) << shift; */
@@ -2983,32 +2979,32 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
new_cs, new_eip, shift, addend);
LOG_PCALL_STATE(env);
if ((new_cs & 0xfffc) == 0) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (load_segment(&e1, &e2, new_cs) != 0) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
if (!(e2 & DESC_S_MASK) ||
!(e2 & DESC_CS_MASK)) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
cpl = env->hflags & HF_CPL_MASK;
rpl = new_cs & 3;
if (rpl < cpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
if (e2 & DESC_C_MASK) {
if (dpl > rpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
} else {
if (dpl != rpl) {
- raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
}
}
if (!(e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);
}
sp += addend;
@@ -3056,26 +3052,26 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
} else
#endif
{
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
} else {
if ((new_ss & 3) != rpl) {
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
if (load_segment(&ss_e1, &ss_e2, new_ss) != 0) {
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
if (!(ss_e2 & DESC_S_MASK) ||
(ss_e2 & DESC_CS_MASK) ||
!(ss_e2 & DESC_W_MASK)) {
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
if (dpl != rpl) {
- raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ raise_exception_err(env, EXCP0D_GPF, new_ss & 0xfffc);
}
if (!(ss_e2 & DESC_P_MASK)) {
- raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
+ raise_exception_err(env, EXCP0B_NOSEG, new_ss & 0xfffc);
}
cpu_x86_load_seg_cache(env, R_SS, new_ss,
get_seg_base(ss_e1, ss_e2),
@@ -3157,20 +3153,20 @@ void helper_iret_protected(int shift, int next_eip)
if (env->eflags & NT_MASK) {
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
#endif
tss_selector = lduw_kernel(env->tr.base + 0);
if (tss_selector & 4) {
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
if (load_segment(&e1, &e2, tss_selector) != 0) {
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
type = (e2 >> DESC_TYPE_SHIFT) & 0x17;
/* NOTE: we check both segment and busy TSS */
if (type != 3) {
- raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
+ raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);
}
switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
} else {
@@ -3187,7 +3183,7 @@ void helper_lret_protected(int shift, int addend)
void helper_sysenter(void)
{
if (env->sysenter_cs == 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
env->eflags &= ~(VM_MASK | IF_MASK | RF_MASK);
cpu_x86_set_cpl(env, 0);
@@ -3224,7 +3220,7 @@ void helper_sysexit(int dflag)
cpl = env->hflags & HF_CPL_MASK;
if (env->sysenter_cs == 0 || cpl != 0) {
- raise_exception_err(EXCP0D_GPF, 0);
+ raise_exception_err(env, EXCP0D_GPF, 0);
}
cpu_x86_set_cpl(env, 3);
#ifdef TARGET_X86_64
@@ -3364,7 +3360,7 @@ void helper_rdtsc(void)
uint64_t val;
if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
helper_svm_check_intercept_param(SVM_EXIT_RDTSC, 0);
@@ -3382,13 +3378,13 @@ void helper_rdtscp(void)
void helper_rdpmc(void)
{
if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
helper_svm_check_intercept_param(SVM_EXIT_RDPMC, 0);
/* currently unimplemented */
qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n");
- raise_exception_err(EXCP06_ILLOP, 0);
+ raise_exception_err(env, EXCP06_ILLOP, 0);
}
#if defined(CONFIG_USER_ONLY)
@@ -3900,7 +3896,7 @@ static inline floatx80 helper_fdiv(floatx80 a, floatx80 b)
static void fpu_raise_exception(void)
{
if (env->cr[0] & CR0_NE_MASK) {
- raise_exception(EXCP10_COPR);
+ raise_exception(env, EXCP10_COPR);
}
#if !defined(CONFIG_USER_ONLY)
else {
@@ -4894,7 +4890,7 @@ void helper_fxsave(target_ulong ptr, int data64)
/* The operand must be 16 byte aligned */
if (ptr & 0xf) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
@@ -4956,7 +4952,7 @@ void helper_fxrstor(target_ulong ptr, int data64)
/* The operand must be 16 byte aligned */
if (ptr & 0xf) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
env->fpuc = lduw(ptr);
@@ -5144,12 +5140,12 @@ void helper_divq_EAX(target_ulong t0)
uint64_t r0, r1;
if (t0 == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
r0 = EAX;
r1 = EDX;
if (div64(&r0, &r1, t0)) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
EAX = r0;
EDX = r1;
@@ -5160,12 +5156,12 @@ void helper_idivq_EAX(target_ulong t0)
uint64_t r0, r1;
if (t0 == 0) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
r0 = EAX;
r1 = EDX;
if (idiv64(&r0, &r1, t0)) {
- raise_exception(EXCP00_DIVZ);
+ raise_exception(env, EXCP00_DIVZ);
}
EAX = r0;
EDX = r1;
@@ -5191,7 +5187,7 @@ void helper_hlt(int next_eip_addend)
void helper_monitor(target_ulong ptr)
{
if ((uint32_t)ECX != 0) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
/* XXX: store address? */
helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0);
@@ -5200,7 +5196,7 @@ void helper_monitor(target_ulong ptr)
void helper_mwait(int next_eip_addend)
{
if ((uint32_t)ECX != 0) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0);
EIP += next_eip_addend;
@@ -5225,14 +5221,14 @@ void helper_reset_rf(void)
env->eflags &= ~RF_MASK;
}
-void helper_raise_interrupt(int intno, int next_eip_addend)
+void helper_raise_interrupt(CPUX86State *env, int intno, int next_eip_addend)
{
- raise_interrupt(intno, 1, 0, next_eip_addend);
+ raise_interrupt(env, intno, 1, 0, next_eip_addend);
}
-void helper_raise_exception(int exception_index)
+void helper_raise_exception(CPUX86State *env, int exception_index)
{
- raise_exception(exception_index);
+ raise_exception(env, exception_index);
}
void helper_cli(void)
@@ -5256,7 +5252,7 @@ void helper_sti_vm(void)
{
env->eflags |= VIF_MASK;
if (env->eflags & VIP_MASK) {
- raise_exception(EXCP0D_GPF);
+ raise_exception(env, EXCP0D_GPF);
}
}
#endif
@@ -5279,7 +5275,7 @@ void helper_boundw(target_ulong a0, int v)
high = ldsw(a0 + 2);
v = (int16_t)v;
if (v < low || v > high) {
- raise_exception(EXCP05_BOUND);
+ raise_exception(env, EXCP05_BOUND);
}
}
@@ -5290,7 +5286,7 @@ void helper_boundl(target_ulong a0, int v)
low = ldl(a0);
high = ldl(a0 + 4);
if (v < low || v > high) {
- raise_exception(EXCP05_BOUND);
+ raise_exception(env, EXCP05_BOUND);
}
}
@@ -5338,7 +5334,7 @@ void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx,
cpu_restore_state(tb, env, retaddr);
}
}
- raise_exception_err(env->exception_index, env->error_code);
+ raise_exception_err(env, env->exception_index, env->error_code);
}
env = saved_env;
}
@@ -5384,11 +5380,16 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
{
}
+void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1)
+{
+}
+
void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
{
}
-void svm_check_intercept(CPUX86State *env1, uint32_t type)
+void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
+ uint64_t param)
{
}
@@ -5605,7 +5606,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
env->exception_next_eip = -1;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
/* XXX: is it always correct? */
- do_interrupt_all(vector, 0, 0, 0, 1);
+ do_interrupt_x86_hardirq(env, vector, 1);
break;
case SVM_EVTINJ_TYPE_NMI:
env->exception_index = EXCP02_NMI;
@@ -5640,7 +5641,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
void helper_vmmcall(void)
{
helper_svm_check_intercept_param(SVM_EXIT_VMMCALL, 0);
- raise_exception(EXCP06_ILLOP);
+ raise_exception(env, EXCP06_ILLOP);
}
void helper_vmload(int aflag)
@@ -5741,7 +5742,7 @@ void helper_skinit(void)
{
helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0);
/* XXX: not implemented */
- raise_exception(EXCP06_ILLOP);
+ raise_exception(env, EXCP06_ILLOP);
}
void helper_invlpga(int aflag)
@@ -5834,13 +5835,14 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
}
}
-void svm_check_intercept(CPUX86State *env1, uint32_t type)
+void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
+ uint64_t param)
{
CPUX86State *saved_env;
saved_env = env;
env = env1;
- helper_svm_check_intercept_param(type, 0);
+ helper_svm_check_intercept_param(type, param);
env = saved_env;
}
@@ -6022,6 +6024,12 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
cpu_loop_exit(env);
}
+void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1)
+{
+ env = nenv;
+ helper_vmexit(exit_code, exit_info_1);
+}
+
#endif
/* MMX/SSE */
diff --git a/target-i386/translate.c b/target-i386/translate.c
index c1ede1a756..8ac6132d13 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2659,7 +2659,7 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- gen_helper_raise_exception(tcg_const_i32(trapno));
+ gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->is_jmp = DISAS_TB_JUMP;
}
@@ -2671,7 +2671,7 @@ static void gen_interrupt(DisasContext *s, int intno,
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(cur_eip);
- gen_helper_raise_interrupt(tcg_const_i32(intno),
+ gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
tcg_const_i32(next_eip - cur_eip));
s->is_jmp = DISAS_TB_JUMP;
}
diff --git a/user-exec.c b/user-exec.c
index d8c2ad9f2f..b2a4261eca 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -41,7 +41,7 @@
static void exception_action(CPUArchState *env1)
{
#if defined(TARGET_I386)
- raise_exception_err_env(env1, env1->exception_index, env1->error_code);
+ raise_exception_err(env1, env1->exception_index, env1->error_code);
#else
cpu_loop_exit(env1);
#endif