Ignore CS.L bit when EFER.LMA is not set

Add potentially missed CPU mode change in SYSCALL/RET/ENTER/EXIT
This commit is contained in:
Stanislav Shwartsman 2008-04-20 18:10:32 +00:00
parent 57a8e24615
commit a91ef4e31b
2 changed files with 18 additions and 7 deletions

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer_pro.cc,v 1.71 2008-03-31 20:56:27 sshwarts Exp $
// $Id: ctrl_xfer_pro.cc,v 1.72 2008-04-20 18:10:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -50,10 +50,9 @@ void BX_CPU_C::check_cs(bx_descriptor_t *descriptor, Bit16u cs_raw, Bit8u check_
#if BX_SUPPORT_X86_64
if (descriptor->u.segment.l) {
if (! BX_CPU_THIS_PTR efer.get_LMA()) {
BX_PANIC(("check_cs(0x%04x): attempt to jump to long mode without enabling EFER.LMA !", cs_raw));
BX_ERROR(("check_cs(0x%04x): attempt to jump to long mode without enabling EFER.LMA !", cs_raw));
}
if (descriptor->u.segment.d_b) {
else if (descriptor->u.segment.d_b) {
BX_ERROR(("check_cs(0x%04x): Both L and D bits enabled for segment descriptor !", cs_raw));
exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
}
@ -102,7 +101,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
(0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl;
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR efer.get_LMA()) {
if (long_mode()) {
if (descriptor->u.segment.l) {
loadSRegLMNominal(BX_SEG_REG_CS, selector->value, cpl);
}
@ -143,7 +142,7 @@ void BX_CPU_C::branch_far64(bx_selector_t *selector,
bx_descriptor_t *descriptor, bx_address rip, Bit8u cpl)
{
#if BX_SUPPORT_X86_64
if (descriptor->u.segment.l) {
if (long_mode() && descriptor->u.segment.l) {
if (! IsCanonical(rip)) {
BX_ERROR(("branch_far: canonical RIP violation"));
exception(BX_GP_EXCEPTION, 0, 0);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.215 2008-04-19 22:29:44 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.216 2008-04-20 18:10:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1286,6 +1286,10 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(Bit32u val_32)
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with CS.L !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
BX_ERROR(("SetCR0: attempt to enter x86-64 long mode with TSS286 in TR !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
BX_CPU_THIS_PTR efer.set_LMA(1);
}
}
@ -2129,6 +2133,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSENTER(bxInstruction_c *i)
EIP = (Bit32u) BX_CPU_THIS_PTR msr.sysenter_eip_msr;
}
handleCpuModeChange();
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSENTER,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
#else
@ -2236,6 +2242,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSEXIT(bxInstruction_c *i)
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.l = 0;
#endif
handleCpuModeChange();
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSEXIT,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
#else
@ -2369,6 +2377,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSCALL(bxInstruction_c *i)
RIP = temp_RIP;
}
handleCpuModeChange();
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSCALL,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
}
@ -2500,6 +2510,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SYSRET(bxInstruction_c *i)
temp_RIP = ECX;
}
handleCpuModeChange();
RIP = temp_RIP;
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_SYSRET,