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 24 #if 0
25 25 #define raise_exception_err(a, b)\
26 26 do {\
27   - fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
  27 + if (logfile)\
  28 + fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
28 29 (raise_exception_err)(a, b);\
29 30 } while (0)
30 31 #endif
... ... @@ -215,11 +216,11 @@ static void tss_load_seg(int seg_reg, int selector)
215 216 if (seg_reg == R_CS) {
216 217 if (!(e2 & DESC_CS_MASK))
217 218 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
  219 + /* XXX: is it correct ? */
218 220 if (dpl != rpl)
219 221 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
220 222 if ((e2 & DESC_C_MASK) && dpl > rpl)
221 223 raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
222   -
223 224 } else if (seg_reg == R_SS) {
224 225 /* SS must be writable data */
225 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 891 esp = get_rsp_from_tss(ist + 3);
891 892 else
892 893 esp = get_rsp_from_tss(dpl);
  894 + esp &= ~0xfLL; /* align stack */
893 895 ss = 0;
894 896 new_stack = 1;
895 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 899 if (env->eflags & VM_MASK)
898 900 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
899 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 907 dpl = cpl;
902 908 } else {
903 909 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
... ... @@ -946,8 +952,12 @@ void helper_syscall(int next_eip_addend)
946 952 selector = (env->star >> 32) & 0xffff;
947 953 #ifdef TARGET_X86_64
948 954 if (env->hflags & HF_LMA_MASK) {
  955 + int code64;
  956 +
949 957 ECX = env->eip + next_eip_addend;
950 958 env->regs[11] = compute_eflags();
  959 +
  960 + code64 = env->hflags & HF_CS64_MASK;
951 961  
952 962 cpu_x86_set_cpl(env, 0);
953 963 cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
... ... @@ -961,7 +971,7 @@ void helper_syscall(int next_eip_addend)
961 971 DESC_S_MASK |
962 972 DESC_W_MASK | DESC_A_MASK);
963 973 env->eflags &= ~env->fmask;
964   - if (env->hflags & HF_CS64_MASK)
  974 + if (code64)
965 975 env->eip = env->lstar;
966 976 else
967 977 env->eip = env->cstar;
... ...