Commit 9540a78b90c9c0240d9054b5b80de8d1a16a489e

Authored by bellard
1 parent e10c2bfb

x86_64 stack alignment fixes - x86_64 32 bit syscall fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1769 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 14 additions and 4 deletions
target-i386/helper.c
@@ -24,7 +24,8 @@ @@ -24,7 +24,8 @@
24 #if 0 24 #if 0
25 #define raise_exception_err(a, b)\ 25 #define raise_exception_err(a, b)\
26 do {\ 26 do {\
27 - fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ 27 + if (logfile)\
  28 + fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
28 (raise_exception_err)(a, b);\ 29 (raise_exception_err)(a, b);\
29 } while (0) 30 } while (0)
30 #endif 31 #endif
@@ -215,11 +216,11 @@ static void tss_load_seg(int seg_reg, int selector) @@ -215,11 +216,11 @@ static void tss_load_seg(int seg_reg, int selector)
215 if (seg_reg == R_CS) { 216 if (seg_reg == R_CS) {
216 if (!(e2 & DESC_CS_MASK)) 217 if (!(e2 & DESC_CS_MASK))
217 raise_exception_err(EXCP0A_TSS, selector & 0xfffc); 218 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
  219 + /* XXX: is it correct ? */
218 if (dpl != rpl) 220 if (dpl != rpl)
219 raise_exception_err(EXCP0A_TSS, selector & 0xfffc); 221 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
220 if ((e2 & DESC_C_MASK) && dpl > rpl) 222 if ((e2 & DESC_C_MASK) && dpl > rpl)
221 raise_exception_err(EXCP0A_TSS, selector & 0xfffc); 223 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
222 -  
223 } else if (seg_reg == R_SS) { 224 } else if (seg_reg == R_SS) {
224 /* SS must be writable data */ 225 /* SS must be writable data */
225 if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) 226 if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
@@ -890,6 +891,7 @@ static void do_interrupt64(int intno, int is_int, int error_code, @@ -890,6 +891,7 @@ static void do_interrupt64(int intno, int is_int, int error_code,
890 esp = get_rsp_from_tss(ist + 3); 891 esp = get_rsp_from_tss(ist + 3);
891 else 892 else
892 esp = get_rsp_from_tss(dpl); 893 esp = get_rsp_from_tss(dpl);
  894 + esp &= ~0xfLL; /* align stack */
893 ss = 0; 895 ss = 0;
894 new_stack = 1; 896 new_stack = 1;
895 } else if ((e2 & DESC_C_MASK) || dpl == cpl) { 897 } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
@@ -897,7 +899,11 @@ static void do_interrupt64(int intno, int is_int, int error_code, @@ -897,7 +899,11 @@ static void do_interrupt64(int intno, int is_int, int error_code,
897 if (env->eflags & VM_MASK) 899 if (env->eflags & VM_MASK)
898 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 900 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
899 new_stack = 0; 901 new_stack = 0;
900 - esp = ESP & ~0xf; /* align stack */ 902 + if (ist != 0)
  903 + esp = get_rsp_from_tss(ist + 3);
  904 + else
  905 + esp = ESP;
  906 + esp &= ~0xfLL; /* align stack */
901 dpl = cpl; 907 dpl = cpl;
902 } else { 908 } else {
903 raise_exception_err(EXCP0D_GPF, selector & 0xfffc); 909 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
@@ -946,8 +952,12 @@ void helper_syscall(int next_eip_addend) @@ -946,8 +952,12 @@ void helper_syscall(int next_eip_addend)
946 selector = (env->star >> 32) & 0xffff; 952 selector = (env->star >> 32) & 0xffff;
947 #ifdef TARGET_X86_64 953 #ifdef TARGET_X86_64
948 if (env->hflags & HF_LMA_MASK) { 954 if (env->hflags & HF_LMA_MASK) {
  955 + int code64;
  956 +
949 ECX = env->eip + next_eip_addend; 957 ECX = env->eip + next_eip_addend;
950 env->regs[11] = compute_eflags(); 958 env->regs[11] = compute_eflags();
  959 +
  960 + code64 = env->hflags & HF_CS64_MASK;
951 961
952 cpu_x86_set_cpl(env, 0); 962 cpu_x86_set_cpl(env, 0);
953 cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, 963 cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
@@ -961,7 +971,7 @@ void helper_syscall(int next_eip_addend) @@ -961,7 +971,7 @@ void helper_syscall(int next_eip_addend)
961 DESC_S_MASK | 971 DESC_S_MASK |
962 DESC_W_MASK | DESC_A_MASK); 972 DESC_W_MASK | DESC_A_MASK);
963 env->eflags &= ~env->fmask; 973 env->eflags &= ~env->fmask;
964 - if (env->hflags & HF_CS64_MASK) 974 + if (code64)
965 env->eip = env->lstar; 975 env->eip = env->lstar;
966 else 976 else
967 env->eip = env->cstar; 977 env->eip = env->cstar;