optimization + fix

This commit is contained in:
Stanislav Shwartsman 2010-04-03 16:52:33 +00:00
parent 393ec36da1
commit a445b5c4f3
4 changed files with 45 additions and 50 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: crregs.cc,v 1.5 2010-04-03 05:59:07 sshwarts Exp $
// $Id: crregs.cc,v 1.6 2010-04-03 16:52:32 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2010 Stanislav Shwartsman
@ -426,14 +426,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
case 3: // CR3
#if BX_SUPPORT_VMX
VMexit_CR3_Write(i, val_32);
#endif
#if BX_CPU_LEVEL >= 6
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
if (! CheckPDPTR(val_32)) {
BX_ERROR(("SetCR3(): PDPTR check failed !"));
exception(BX_GP_EXCEPTION, 0);
}
}
#endif
if (! SetCR3(val_32))
exception(BX_GP_EXCEPTION, 0);
@ -554,7 +546,6 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
#if BX_SUPPORT_VMX
VMexit_CR3_Write(i, val_64);
#endif
// no PDPTR checks in long mode
if (! SetCR3(val_64))
exception(BX_GP_EXCEPTION, 0);
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_MOV_CR3, val_64);
@ -1045,7 +1036,17 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR3(bx_address val)
}
else
#endif
{
// legacy PAE mode - check PDPTRs validity
if (BX_CPU_THIS_PTR cr0.get_PG()) {
if (! CheckPDPTR(val)) {
BX_ERROR(("SetCR3(): PDPTR check failed !"));
return 0;
}
}
BX_CPU_THIS_PTR cr3_masked = val & 0xffffffe0;
}
}
else
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.207 2010-04-03 07:30:23 sshwarts Exp $
// $Id: paging.cc,v 1.208 2010-04-03 16:52:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2010 The Bochs Project
@ -253,7 +253,7 @@
// | +------------> u/s of current access
// +---------------> Current CR0.WP value
static unsigned priv_check[BX_PRIV_CHECK_SIZE];
static Bit8u priv_check[BX_PRIV_CHECK_SIZE];
#define BX_PAGING_PHY_ADDRESS_RESERVED_BITS \
(BX_PHY_ADDRESS_RESERVED_BITS & BX_CONST64(0xfffffffffffff))
@ -442,8 +442,6 @@ void BX_CPU_C::TLB_flushNonGlobal(void)
BX_CPU_THIS_PTR TLB.split_large = 1;
}
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 0;
#if BX_SUPPORT_MONITOR_MWAIT
// invalidating of the TLB might change translation for monitored page
// and cause subsequent MWAIT instruction to wait forever
@ -681,7 +679,7 @@ static const char *bx_paging_level[4] = { "PTE", "PDE", "PDPE", "PML4" };
// Translate a linear address to a physical address in long mode
bx_phy_address BX_CPU_C::translate_linear_long_mode(bx_address laddr, bx_address &lpf_mask, Bit32u &combined_access, unsigned curr_pl, unsigned rw)
{
bx_phy_address entry_addr[4], ppf, pbase = BX_CPU_THIS_PTR cr3_masked;
bx_phy_address entry_addr[4], ppf = BX_CPU_THIS_PTR cr3_masked;
Bit64u entry[4];
bx_bool nx_fault = 0;
unsigned pl = (curr_pl == 3);
@ -689,7 +687,7 @@ bx_phy_address BX_CPU_C::translate_linear_long_mode(bx_address laddr, bx_address
combined_access = 0x06;
for (leaf = BX_LEVEL_PML4;; --leaf) {
entry_addr[leaf] = pbase + 8 * ((laddr >> (12 + 9*leaf)) & 511);
entry_addr[leaf] = ppf + 8 * ((laddr >> (12 + 9*leaf)) & 511);
access_read_physical(entry_addr[leaf], 8, &entry[leaf]);
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, entry_addr[leaf], 8, BX_READ, (Bit8u*)(&entry[leaf]));
@ -699,13 +697,9 @@ bx_phy_address BX_CPU_C::translate_linear_long_mode(bx_address laddr, bx_address
page_fault(fault, laddr, pl, rw);
combined_access &= curr_entry & 0x06; // U/S and R/W
pbase = curr_entry & BX_CONST64(0x000ffffffffff000);
ppf = curr_entry & BX_CONST64(0x000ffffffffff000);
if (leaf == BX_LEVEL_PTE) {
// Make up the physical page frame address.
ppf = (bx_phy_address)(curr_entry & BX_CONST64(0x000ffffffffff000));
break;
}
if (leaf == BX_LEVEL_PTE) break;
if (curr_entry & 0x80) {
if (leaf > (BX_LEVEL_PDE + BX_SUPPORT_1G_PAGES)) {
@ -791,21 +785,26 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::CheckPDPTR(Bit32u cr3_val)
{
cr3_val &= 0xffffffe0;
for (int n=0; n<4; n++) {
// read PDPTE cache entry
bx_phy_address entry_pdpe_addr = (bx_phy_address) (cr3_val | (n << 3));
access_read_physical(entry_pdpe_addr, 8, &(BX_CPU_THIS_PTR PDPTR_CACHE.entry[n]));
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, entry_pdpe_addr, 8,
BX_READ, (Bit8u*)(&BX_CPU_THIS_PTR PDPTR_CACHE.entry[n]));
Bit64u pdptr = BX_CPU_THIS_PTR PDPTR_CACHE.entry[n];
if (pdptr & 0x1) {
if (pdptr & PAGING_PAE_PDPTE_RESERVED_BITS) {
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 0;
return 0;
}
}
Bit64u pdptr[4];
int n;
for (n=0; n<4; n++) {
// read and check PDPTE entries
bx_phy_address pdpe_entry_addr = (bx_phy_address) (cr3_val | (n << 3));
access_read_physical(pdpe_entry_addr, 8, &(pdptr[n]));
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pdpe_entry_addr, 8, BX_READ, (Bit8u*) &(pdptr[n]));
if (pdptr[n] & 0x1) {
if (pdptr[n] & PAGING_PAE_PDPTE_RESERVED_BITS) {
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 0;
return 0;
}
}
}
// load new PDPTRs
for (n=0; n<4; n++)
BX_CPU_THIS_PTR PDPTR_CACHE.entry[n] = pdptr[n];
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 1;
return 1; /* PDPTRs are fine */
@ -1193,17 +1192,19 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
goto page_fault;
pt_address = bx_phy_address(pte & BX_CONST64(0x000ffffffffff000));
if (pte & 0x80) {
if (level == 1) { // 2M page
if (level == BX_LEVEL_PDE) { // 2M page
offset_mask = 0x1fffff;
pt_address &= BX_CONST64(0x000fffffffffe000);
break;
}
#if BX_SUPPORT_1G_PAGES
if (level == 2 && long_mode()) { // 1G page
if (level == BX_LEVEL_PDPE && long_mode()) { // 1G page
offset_mask = 0x3fffffff;
pt_address &= BX_CONST64(0x000fffffffffe000);
break;
}
#endif
if (level != 0)
if (level != BX_LEVEL_PTE)
goto page_fault;
}
}
@ -1219,7 +1220,7 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
if (!(pte & 1))
goto page_fault;
pt_address = pte & 0xfffff000;
if (level == 1 && (pte & 0x80)) { // PSE page
if (level == BX_LEVEL_PDE && (pte & 0x80)) { // PSE page
offset_mask = 0x3fffff;
#if BX_PHY_ADDRESS_WIDTH > 32
pt_address += ((bx_phy_address)(pte & 0x003fe000)) << 19;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: tasking.cc,v 1.89 2010-03-25 21:57:26 sshwarts Exp $
// $Id: tasking.cc,v 1.90 2010-04-03 16:52:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2010 The Bochs Project
@ -468,14 +468,6 @@ void BX_CPU_C::task_switch(bxInstruction_c *i, bx_selector_t *tss_selector,
// change CR3 only if it actually modified
if (newCR3 != BX_CPU_THIS_PTR cr3) {
BX_DEBUG(("task_switch changing CR3 to 0x" FMT_PHY_ADDRX, newCR3));
#if BX_CPU_LEVEL >= 6
if (BX_CPU_THIS_PTR cr0.get_PG() && BX_CPU_THIS_PTR cr4.get_PAE()) {
if (! CheckPDPTR(newCR3)) {
BX_ERROR(("task_switch(): PDPTR check failed !"));
exception(BX_GP_EXCEPTION, 0);
}
}
#endif
if (! SetCR3(newCR3)) // Tell paging unit about new cr3 value
exception(BX_GP_EXCEPTION, 0);
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_TASKSWITCH, newCR3);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: vmx.cc,v 1.54 2010-04-03 07:30:23 sshwarts Exp $
// $Id: vmx.cc,v 1.55 2010-04-03 16:52:33 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2009-2010 Stanislav Shwartsman
@ -1737,7 +1737,8 @@ void BX_CPU_C::VMexitLoadHostState(void)
TLB_flush(); // CR0/CR4 updated
if (! SetCR3(host_state->cr3)) {
BX_PANIC(("VMEXIT CR3 is broken !"));
BX_ERROR(("VMABORT: host CR3 is broken !"));
VMabort(VMABORT_HOST_PDPTR_CORRUPTED);
}
BX_CPU_THIS_PTR dr7 = 0x00000400;