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
This commit is contained in:
bellard 2006-03-03 01:54:40 +00:00
parent e10c2bfb73
commit 9540a78b90

View File

@ -24,7 +24,8 @@
#if 0 #if 0
#define raise_exception_err(a, b)\ #define raise_exception_err(a, b)\
do {\ do {\
fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ if (logfile)\
fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
(raise_exception_err)(a, b);\ (raise_exception_err)(a, b);\
} while (0) } while (0)
#endif #endif
@ -215,11 +216,11 @@ static void tss_load_seg(int seg_reg, int selector)
if (seg_reg == R_CS) { if (seg_reg == R_CS) {
if (!(e2 & DESC_CS_MASK)) if (!(e2 & DESC_CS_MASK))
raise_exception_err(EXCP0A_TSS, selector & 0xfffc); raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
/* XXX: is it correct ? */
if (dpl != rpl) if (dpl != rpl)
raise_exception_err(EXCP0A_TSS, selector & 0xfffc); raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
if ((e2 & DESC_C_MASK) && dpl > rpl) if ((e2 & DESC_C_MASK) && dpl > rpl)
raise_exception_err(EXCP0A_TSS, selector & 0xfffc); raise_exception_err(EXCP0A_TSS, selector & 0xfffc);
} else if (seg_reg == R_SS) { } else if (seg_reg == R_SS) {
/* SS must be writable data */ /* SS must be writable data */
if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) 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,
esp = get_rsp_from_tss(ist + 3); esp = get_rsp_from_tss(ist + 3);
else else
esp = get_rsp_from_tss(dpl); esp = get_rsp_from_tss(dpl);
esp &= ~0xfLL; /* align stack */
ss = 0; ss = 0;
new_stack = 1; new_stack = 1;
} else if ((e2 & DESC_C_MASK) || dpl == cpl) { } else if ((e2 & DESC_C_MASK) || dpl == cpl) {
@ -897,7 +899,11 @@ static void do_interrupt64(int intno, int is_int, int error_code,
if (env->eflags & VM_MASK) if (env->eflags & VM_MASK)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
new_stack = 0; new_stack = 0;
esp = ESP & ~0xf; /* align stack */ if (ist != 0)
esp = get_rsp_from_tss(ist + 3);
else
esp = ESP;
esp &= ~0xfLL; /* align stack */
dpl = cpl; dpl = cpl;
} else { } else {
raise_exception_err(EXCP0D_GPF, selector & 0xfffc); raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
@ -946,8 +952,12 @@ void helper_syscall(int next_eip_addend)
selector = (env->star >> 32) & 0xffff; selector = (env->star >> 32) & 0xffff;
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK) { if (env->hflags & HF_LMA_MASK) {
int code64;
ECX = env->eip + next_eip_addend; ECX = env->eip + next_eip_addend;
env->regs[11] = compute_eflags(); env->regs[11] = compute_eflags();
code64 = env->hflags & HF_CS64_MASK;
cpu_x86_set_cpl(env, 0); cpu_x86_set_cpl(env, 0);
cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
@ -961,7 +971,7 @@ void helper_syscall(int next_eip_addend)
DESC_S_MASK | DESC_S_MASK |
DESC_W_MASK | DESC_A_MASK); DESC_W_MASK | DESC_A_MASK);
env->eflags &= ~env->fmask; env->eflags &= ~env->fmask;
if (env->hflags & HF_CS64_MASK) if (code64)
env->eip = env->lstar; env->eip = env->lstar;
else else
env->eip = env->cstar; env->eip = env->cstar;