Commit 9540a78b90c9c0240d9054b5b80de8d1a16a489e
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; | ... | ... |