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,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; |