]> git.proxmox.com Git - qemu.git/commitdiff
fixed ljmp and iret to TSS
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 26 Mar 2004 22:26:53 +0000 (22:26 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 26 Mar 2004 22:26:53 +0000 (22:26 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@682 c046a42c-6fe2-441c-8c8c-71466251a162

target-i386/exec.h
target-i386/helper.c
target-i386/op.c
target-i386/translate.c

index 3f6ddf1b4b0ebd346b8d49be43b1b81e2b014cda..63010f745dfacf4eb53ffd3bc85af2da966ad405 100644 (file)
@@ -123,11 +123,11 @@ typedef struct CCTable {
 extern CCTable cc_table[];
 
 void load_seg(int seg_reg, int selector);
-void helper_ljmp_protected_T0_T1(void);
+void helper_ljmp_protected_T0_T1(int next_eip);
 void helper_lcall_real_T0_T1(int shift, int next_eip);
 void helper_lcall_protected_T0_T1(int shift, int next_eip);
 void helper_iret_real(int shift);
-void helper_iret_protected(int shift);
+void helper_iret_protected(int shift, int next_eip);
 void helper_lret_protected(int shift, int addend);
 void helper_lldt_T0(void);
 void helper_ltr_T0(void);
index 6239436315ceb0bd600358f71d699851c505e892..dbdabd82ee685ff3162b21eeebf3a47594d09420 100644 (file)
@@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector)
 }
 
 /* protected mode jump */
-void helper_ljmp_protected_T0_T1(void)
+void helper_ljmp_protected_T0_T1(int next_eip)
 {
     int new_cs, new_eip, gate_cs, type;
     uint32_t e1, e2, cpl, dpl, rpl, limit;
@@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void)
         case 5: /* task gate */
             if (dpl < cpl || dpl < rpl)
                 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
-            /* XXX: check if it is really the current EIP */
-            switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, env->eip);
+            switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
             break;
         case 4: /* 286 call gate */
         case 12: /* 386 call gate */
@@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
     ESP = new_esp;
 }
 
-void helper_iret_protected(int shift)
+void helper_iret_protected(int shift, int next_eip)
 {
     int tss_selector, type;
     uint32_t e1, e2;
@@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift)
         /* NOTE: we check both segment and busy TSS */
         if (type != 3)
             raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
-        /* XXX: check if it is really the current EIP */
-        switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, env->eip);
+        switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
     } else {
         helper_ret_protected(shift, 1, 0);
     }
index f592b67a6af25ba316f027a0f0afac4cd1651082..1169f121adc2de71928dc34535d201b3a1ab42e4 100644 (file)
@@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void)
 /* T0: segment, T1:eip */
 void OPPROTO op_ljmp_protected_T0_T1(void)
 {
-    helper_ljmp_protected_T0_T1();
+    helper_ljmp_protected_T0_T1(PARAM1);
 }
 
 void OPPROTO op_lcall_real_T0_T1(void)
@@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void)
 
 void OPPROTO op_iret_protected(void)
 {
-    helper_iret_protected(PARAM1);
+    helper_iret_protected(PARAM1, PARAM2);
 }
 
 void OPPROTO op_lret_protected(void)
index 12a74435ff444f22b148f57205e2cb74446d40a2..4a1a2767a952bf8ed4a5b6093cf1a8d2a41e253c 100644 (file)
@@ -2172,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
                 if (s->cc_op != CC_OP_DYNAMIC)
                     gen_op_set_cc_op(s->cc_op);
                 gen_op_jmp_im(pc_start - s->cs_base);
-                gen_op_ljmp_protected_T0_T1();
+                gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
             } else {
                 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
                 gen_op_movl_T0_T1();
@@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
             if (s->cc_op != CC_OP_DYNAMIC)
                 gen_op_set_cc_op(s->cc_op);
             gen_op_jmp_im(pc_start - s->cs_base);
-            gen_op_iret_protected(s->dflag);
+            gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
             s->cc_op = CC_OP_EFLAGS;
         }
         gen_eob(s);