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,11 +123,11 @@ typedef struct CCTable {
123 extern CCTable cc_table[]; 123 extern CCTable cc_table[];
124 124
125 void load_seg(int seg_reg, int selector); 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 void helper_lcall_real_T0_T1(int shift, int next_eip); 127 void helper_lcall_real_T0_T1(int shift, int next_eip);
128 void helper_lcall_protected_T0_T1(int shift, int next_eip); 128 void helper_lcall_protected_T0_T1(int shift, int next_eip);
129 void helper_iret_real(int shift); 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 void helper_lret_protected(int shift, int addend); 131 void helper_lret_protected(int shift, int addend);
132 void helper_lldt_T0(void); 132 void helper_lldt_T0(void);
133 void helper_ltr_T0(void); 133 void helper_ltr_T0(void);
target-i386/helper.c
@@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector) @@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector)
1219 } 1219 }
1220 1220
1221 /* protected mode jump */ 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 int new_cs, new_eip, gate_cs, type; 1224 int new_cs, new_eip, gate_cs, type;
1225 uint32_t e1, e2, cpl, dpl, rpl, limit; 1225 uint32_t e1, e2, cpl, dpl, rpl, limit;
@@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void) @@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void)
1267 case 5: /* task gate */ 1267 case 5: /* task gate */
1268 if (dpl < cpl || dpl < rpl) 1268 if (dpl < cpl || dpl < rpl)
1269 raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); 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 break; 1271 break;
1273 case 4: /* 286 call gate */ 1272 case 4: /* 286 call gate */
1274 case 12: /* 386 call gate */ 1273 case 12: /* 386 call gate */
@@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) @@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
1732 ESP = new_esp; 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 int tss_selector, type; 1736 int tss_selector, type;
1738 uint32_t e1, e2; 1737 uint32_t e1, e2;
@@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift) @@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift)
1748 /* NOTE: we check both segment and busy TSS */ 1747 /* NOTE: we check both segment and busy TSS */
1749 if (type != 3) 1748 if (type != 3)
1750 raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); 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 } else { 1751 } else {
1754 helper_ret_protected(shift, 1, 0); 1752 helper_ret_protected(shift, 1, 0);
1755 } 1753 }
target-i386/op.c
@@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void) @@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void)
918 /* T0: segment, T1:eip */ 918 /* T0: segment, T1:eip */
919 void OPPROTO op_ljmp_protected_T0_T1(void) 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 void OPPROTO op_lcall_real_T0_T1(void) 924 void OPPROTO op_lcall_real_T0_T1(void)
@@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void) @@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void)
938 938
939 void OPPROTO op_iret_protected(void) 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 void OPPROTO op_lret_protected(void) 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,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2172 if (s->cc_op != CC_OP_DYNAMIC) 2172 if (s->cc_op != CC_OP_DYNAMIC)
2173 gen_op_set_cc_op(s->cc_op); 2173 gen_op_set_cc_op(s->cc_op);
2174 gen_op_jmp_im(pc_start - s->cs_base); 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 } else { 2176 } else {
2177 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); 2177 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
2178 gen_op_movl_T0_T1(); 2178 gen_op_movl_T0_T1();
@@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3453 if (s->cc_op != CC_OP_DYNAMIC) 3453 if (s->cc_op != CC_OP_DYNAMIC)
3454 gen_op_set_cc_op(s->cc_op); 3454 gen_op_set_cc_op(s->cc_op);
3455 gen_op_jmp_im(pc_start - s->cs_base); 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 s->cc_op = CC_OP_EFLAGS; 3457 s->cc_op = CC_OP_EFLAGS;
3458 } 3458 }
3459 gen_eob(s); 3459 gen_eob(s);