PDPTR checks fix

This commit is contained in:
Stanislav Shwartsman 2010-04-06 19:26:03 +00:00
parent 0b07759d4c
commit 10505dca81
4 changed files with 39 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: crregs.cc,v 1.9 2010-04-04 19:23:47 sshwarts Exp $
// $Id: crregs.cc,v 1.10 2010-04-06 19:26:02 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010 Stanislav Shwartsman
@ -445,16 +445,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
#if BX_SUPPORT_VMX
val_32 = VMexit_CR4_Write(i, val_32);
#endif
#if BX_CPU_LEVEL >= 6
if (BX_CPU_THIS_PTR cr0.get_PG() && (val_32 & (1<<5)) != 0 /* PAE */ && !long_mode()) {
if (! CheckPDPTR(BX_CPU_THIS_PTR cr3)) {
BX_ERROR(("SetCR4(): PDPTR check failed !"));
exception(BX_GP_EXCEPTION, 0);
}
}
#endif
// Protected mode: #GP(0) if attempt to write a 1 to
// any reserved bit of CR4
if (! SetCR4(val_32))
exception(BX_GP_EXCEPTION, 0);
break;
@ -565,7 +555,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
val_64 = VMexit_CR4_Write(i, val_64);
#endif
BX_DEBUG(("MOV_CqRq: write to CR4 of %08x:%08x", GET32H(val_64), GET32L(val_64)));
// no PDPTR checks in long mode
if (! SetCR4(val_64))
exception(BX_GP_EXCEPTION, 0);
break;
@ -1010,16 +999,22 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR4(bx_address val)
{
if (! check_CR4(val)) return 0;
Bit32u oldCR4 = BX_CPU_THIS_PTR cr4.get32();
BX_CPU_THIS_PTR cr4.set32(val);
#if BX_CPU_LEVEL >= 6
// Modification of PGE,PAE,PSE flushes TLB cache according to docs.
if ((oldCR4 & 0x000000b0) != (BX_CPU_THIS_PTR cr4.val32 & 0x000000b0)) {
if ((val & 0x000000b0) != (BX_CPU_THIS_PTR cr4.val32 & 0x000000b0)) {
// reload PDPTR if PGE,PAE or PSE changed
if (BX_CPU_THIS_PTR cr0.get_PG() && (val & (1<<5)) != 0 /* PAE */ && !long_mode()) {
if (! CheckPDPTR(BX_CPU_THIS_PTR cr3)) {
BX_ERROR(("SetCR4(): PDPTR check failed !"));
return 0;
}
}
TLB_flush(); // Flush Global entries also.
}
#endif
BX_CPU_THIS_PTR cr4.set32(val);
return 1;
}
#endif // BX_CPU_LEVEL >= 4

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.237 2010-04-04 09:04:12 sshwarts Exp $
// $Id: init.cc,v 1.238 2010-04-06 19:26:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2009 The Bochs Project
@ -693,12 +693,17 @@ void BX_CPU_C::after_restore_state(void)
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_IA32_V8086) CPL = 3;
}
if (!SetCR0(cr0.val32))
BX_PANIC(("Incorrect CR0 state !"));
TLB_flush();
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
handleAlignmentCheck();
#endif
handleCpuModeChange();
#if BX_SUPPORT_VMX
set_VMCSPTR(BX_CPU_THIS_PTR vmcsptr);
#endif
assert_checks();
invalidate_prefetch_q();
debug(RIP);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.213 2010-04-04 19:23:47 sshwarts Exp $
// $Id: paging.cc,v 1.214 2010-04-06 19:26:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2010 The Bochs Project
@ -413,10 +413,6 @@ void BX_CPU_C::TLB_flush(void)
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
}
#if BX_CPU_LEVEL >= 6
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 0;
#endif
#if BX_CPU_LEVEL >= 5
BX_CPU_THIS_PTR TLB.split_large = 0; // flush whole TLB
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.68 2010-04-05 09:49:26 sshwarts Exp $
// $Id: smm.cc,v 1.69 2010-04-06 19:26:03 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2009 Stanislav Shwartsman
@ -557,7 +557,7 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
}
// shutdown if write to reserved CR4 bits
if (! SetCR4(temp_cr4)) {
if (!SetCR4(temp_cr4)) {
BX_PANIC(("SMM restore: incorrect CR4 state !"));
return 0;
}
@ -603,6 +603,13 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
return 0;
}
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
if (! CheckPDPTR(temp_cr3)) {
BX_ERROR(("SMM restore: PDPTR check failed !"));
return 0;
}
}
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
Bit64u val_64 = SMRAM_FIELD64(saved_state,
SMRAM_FIELD_RAX_HI32 + 2*n, SMRAM_FIELD_EAX + 2*n);
@ -763,6 +770,16 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
BX_PANIC(("SMM restore: failed to restore CR3 !"));
return 0;
}
#if BX_CPU_LEVEL >= 6
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE()) {
if (! CheckPDPTR(temp_cr3)) {
BX_ERROR(("SMM restore: PDPTR check failed !"));
return 0;
}
}
#endif
setEFlags(temp_eflags);
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {