Commit 08cea4eef8e17114dcdbce93f95cb111c9d622f6

Authored by bellard
1 parent 883da8e2

fixed ljmp and iret to TSS


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@682 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/exec.h
... ... @@ -123,11 +123,11 @@ typedef struct CCTable {
123 123 extern CCTable cc_table[];
124 124  
125 125 void load_seg(int seg_reg, int selector);
126   -void helper_ljmp_protected_T0_T1(void);
  126 +void helper_ljmp_protected_T0_T1(int next_eip);
127 127 void helper_lcall_real_T0_T1(int shift, int next_eip);
128 128 void helper_lcall_protected_T0_T1(int shift, int next_eip);
129 129 void helper_iret_real(int shift);
130   -void helper_iret_protected(int shift);
  130 +void helper_iret_protected(int shift, int next_eip);
131 131 void helper_lret_protected(int shift, int addend);
132 132 void helper_lldt_T0(void);
133 133 void helper_ltr_T0(void);
... ...
target-i386/helper.c
... ... @@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector)
1219 1219 }
1220 1220  
1221 1221 /* protected mode jump */
1222   -void helper_ljmp_protected_T0_T1(void)
  1222 +void helper_ljmp_protected_T0_T1(int next_eip)
1223 1223 {
1224 1224 int new_cs, new_eip, gate_cs, type;
1225 1225 uint32_t e1, e2, cpl, dpl, rpl, limit;
... ... @@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void)
1267 1267 case 5: /* task gate */
1268 1268 if (dpl < cpl || dpl < rpl)
1269 1269 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
1270   - /* XXX: check if it is really the current EIP */
1271   - switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, env->eip);
  1270 + switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
1272 1271 break;
1273 1272 case 4: /* 286 call gate */
1274 1273 case 12: /* 386 call gate */
... ... @@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1732 1731 ESP = new_esp;
1733 1732 }
1734 1733  
1735   -void helper_iret_protected(int shift)
  1734 +void helper_iret_protected(int shift, int next_eip)
1736 1735 {
1737 1736 int tss_selector, type;
1738 1737 uint32_t e1, e2;
... ... @@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift)
1748 1747 /* NOTE: we check both segment and busy TSS */
1749 1748 if (type != 3)
1750 1749 raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
1751   - /* XXX: check if it is really the current EIP */
1752   - switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, env->eip);
  1750 + switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
1753 1751 } else {
1754 1752 helper_ret_protected(shift, 1, 0);
1755 1753 }
... ...
target-i386/op.c
... ... @@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void)
918 918 /* T0: segment, T1:eip */
919 919 void OPPROTO op_ljmp_protected_T0_T1(void)
920 920 {
921   - helper_ljmp_protected_T0_T1();
  921 + helper_ljmp_protected_T0_T1(PARAM1);
922 922 }
923 923  
924 924 void OPPROTO op_lcall_real_T0_T1(void)
... ... @@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void)
938 938  
939 939 void OPPROTO op_iret_protected(void)
940 940 {
941   - helper_iret_protected(PARAM1);
  941 + helper_iret_protected(PARAM1, PARAM2);
942 942 }
943 943  
944 944 void OPPROTO op_lret_protected(void)
... ...
target-i386/translate.c
... ... @@ -2172,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2172 2172 if (s->cc_op != CC_OP_DYNAMIC)
2173 2173 gen_op_set_cc_op(s->cc_op);
2174 2174 gen_op_jmp_im(pc_start - s->cs_base);
2175   - gen_op_ljmp_protected_T0_T1();
  2175 + gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
2176 2176 } else {
2177 2177 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
2178 2178 gen_op_movl_T0_T1();
... ... @@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3453 3453 if (s->cc_op != CC_OP_DYNAMIC)
3454 3454 gen_op_set_cc_op(s->cc_op);
3455 3455 gen_op_jmp_im(pc_start - s->cs_base);
3456   - gen_op_iret_protected(s->dflag);
  3456 + gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
3457 3457 s->cc_op = CC_OP_EFLAGS;
3458 3458 }
3459 3459 gen_eob(s);
... ...