fixed long mode exception handling

This commit is contained in:
Stanislav Shwartsman 2008-04-11 21:40:36 +00:00
parent 138023fbc7
commit 397e2b6eac
2 changed files with 17 additions and 16 deletions

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: call_far.cc,v 1.29 2008-04-11 18:35:47 sshwarts Exp $
// $Id: call_far.cc,v 1.30 2008-04-11 21:40:36 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005 Stanislav Shwartsman
@ -496,15 +496,16 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
// get new RSP for new privilege level from TSS
get_RSP_from_TSS(cs_descriptor.dpl, &RSP_for_cpl_x);
if (! IsCanonical(RSP_for_cpl_x)) {
BX_ERROR(("call_gate64: canonical address failure %08x%08x",
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
Bit64u old_RSP = RSP;
if (! IsCanonical(RSP_for_cpl_x)) {
// #SS(selector) when changing priviledge level
BX_ERROR(("call_gate64: canonical address failure %08x%08x",
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
exception(BX_GP_EXCEPTION, old_SS & 0xfffc, 0);
}
// push old stack long pointer onto new stack
write_new_stack_qword(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
write_new_stack_qword(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.105 2008-04-08 17:58:56 sshwarts Exp $
// $Id: exception.cc,v 1.106 2008-04-11 21:40:36 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -160,8 +160,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
// if code segment is non-conforming and DPL < CPL then
// INTERRUPT TO INNER PRIVILEGE:
if ((IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type)
&& cs_descriptor.dpl<CPL) || (ist != 0))
if (IS_CODE_SEGMENT_NON_CONFORMING(cs_descriptor.type) && cs_descriptor.dpl<CPL)
{
Bit64u RSP_for_cpl_x;
@ -178,17 +177,18 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
RSP_for_cpl_x &= BX_CONST64(0xfffffffffffffff0);
if (! IsCanonical(RSP_for_cpl_x)) {
BX_ERROR(("interrupt(long mode): canonical address failure %08x%08x",
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit64u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
Bit64u old_RIP = RIP;
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
Bit64u old_RSP = RSP;
if (! IsCanonical(RSP_for_cpl_x)) {
// #SS(selector) when changing priviledge level
BX_ERROR(("interrupt(long mode): canonical address failure %08x%08x",
GET32H(RSP_for_cpl_x), GET32L(RSP_for_cpl_x)));
exception(BX_GP_EXCEPTION, old_SS & 0xfffc, 0);
}
// push old stack long pointer onto new stack
write_new_stack_qword(RSP_for_cpl_x - 8, cs_descriptor.dpl, old_SS);
write_new_stack_qword(RSP_for_cpl_x - 16, cs_descriptor.dpl, old_RSP);