Optimize TLB flush methods

This commit is contained in:
Stanislav Shwartsman 2008-08-13 21:51:54 +00:00
parent 870925d575
commit dcb82ec4bf
7 changed files with 55 additions and 34 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.507 2008-08-12 05:03:51 sshwarts Exp $
// $Id: cpu.h,v 1.508 2008-08-13 21:51:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2994,7 +2994,12 @@ public: // for now...
return translate_linear(laddr, curr_pl, rw, DATA_ACCESS);
}
BX_SMF void TLB_flush(bx_bool invalidateGlobal);
#if BX_SUPPORT_GLOBAL_PAGES
BX_SMF void TLB_flushNonGlobal(void);
#else
#define TLB_flushNonGlobal() TLB_flush()
#endif
BX_SMF void TLB_flush(void);
BX_SMF void TLB_invlpg(bx_address laddr);
BX_SMF void TLB_init(void);
BX_SMF void set_INTR(bx_bool value);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.119 2008-07-26 14:19:06 sshwarts Exp $
// $Id: exception.cc,v 1.120 2008-08-13 21:51:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -254,7 +254,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
write_new_stack_qword_64(RSP - 16, cs_descriptor.dpl, old_RSP);
write_new_stack_qword_64(RSP - 24, cs_descriptor.dpl, read_eflags());
write_new_stack_qword_64(RSP - 32, cs_descriptor.dpl,
write_new_stack_qword_64(RSP - 32, cs_descriptor.dpl,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
write_new_stack_qword_64(RSP - 40, cs_descriptor.dpl, RIP);
RSP -= 40;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.176 2008-08-13 20:54:03 sshwarts Exp $
// $Id: init.cc,v 1.177 2008-08-13 21:51:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -649,7 +649,7 @@ void BX_CPU_C::after_restore_state(void)
SetCR0(cr0.val32);
SetCR3(cr3);
TLB_flush(1);
TLB_flush();
assert_checks();
invalidate_prefetch_q();
debug(RIP);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.150 2008-08-10 20:32:00 sshwarts Exp $
// $Id: paging.cc,v 1.151 2008-08-13 21:51:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -401,7 +401,7 @@ BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
// Additionally, the TLB strategy is based on the current value of
// WP, so if that changes we must also flush the TLB.
if ((oldCR0 & 0x80010001) != (newCR0 & 0x80010001))
TLB_flush(1); // 1 = Flush Global entries also.
TLB_flush(); // Flush Global entries also.
}
void BX_CPP_AttrRegparmN(2)
@ -409,7 +409,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
{
// Modification of PGE,PAE,PSE flushes TLB cache according to docs.
if ((oldCR4 & 0x000000b0) != (newCR4 & 0x000000b0))
TLB_flush(1); // 1 = Flush Global entries also.
TLB_flush(); // Flush Global entries also.
#if BX_SUPPORT_PAE
if ((oldCR4 & 0x00000020) != (newCR4 & 0x00000020)) {
@ -425,7 +425,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
BX_CPU_C::SetCR3(bx_address val)
{
// flush TLB even if value does not change
TLB_flush(0); // 0 = Don't flush Global entries.
TLB_flushNonGlobal(); // Don't flush Global entries.
#if BX_SUPPORT_PAE
if (BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
@ -456,9 +456,6 @@ void BX_CPU_C::TLB_init(void)
{
unsigned n, wp, us_combined, rw_combined, us_current, rw_current;
for (n=0; n<BX_TLB_SIZE; n++)
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
//
// Setup privilege check matrix.
//
@ -490,27 +487,18 @@ void BX_CPU_C::TLB_init(void)
}
}
}
TLB_flush();
}
void BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
void BX_CPU_C::TLB_flush(void)
{
#if InstrumentTLB
if (invalidateGlobal)
InstrTLB_Increment(tlbGlobalFlushes);
else
InstrTLB_Increment(tlbNonGlobalFlushes);
InstrTLB_Increment(tlbGlobalFlushes);
#endif
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
// To be conscious of the native cache line usage, only
// write to (invalidate) entries which need it.
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[n];
if (tlbEntry->lpf != BX_INVALID_TLB_ENTRY) {
#if BX_SUPPORT_GLOBAL_PAGES
if (invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage))
#endif
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
}
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
}
#if BX_SUPPORT_PAE
@ -524,13 +512,41 @@ void BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
#endif
}
#if BX_SUPPORT_GLOBAL_PAGES
void BX_CPU_C::TLB_flushNonGlobal(void)
{
#if InstrumentTLB
InstrTLB_Increment(tlbNonGlobalFlushes);
#endif
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[n];
if (!(tlbEntry->accessBits & TLB_GlobalPage))
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
}
#if BX_SUPPORT_PAE
BX_CPU_THIS_PTR PDPE_CACHE.valid = 0;
#endif
#if BX_SUPPORT_MONITOR_MWAIT
// invalidating of the TLB might change translation for monitored page
// and cause subsequent MWAIT instruction to wait forever
BX_CPU_THIS_PTR monitor.reset_monitor();
#endif
}
#endif
void BX_CPU_C::TLB_invlpg(bx_address laddr)
{
BX_DEBUG(("TLB_invlpg(0x"FMT_ADDRX"): invalidate TLB entry", laddr));
unsigned TLB_index = BX_TLB_INDEX_OF(laddr, 0);
bx_address lpf = LPFOf(laddr);
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index];
if (tlbEntry->lpf == LPFOf(laddr)) {
if (tlbEntry->lpf == lpf) {
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.252 2008-08-09 19:18:09 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.253 2008-08-13 21:51:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1772,7 +1772,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
#endif
BX_CPU_THIS_PTR local_apic.set_base(BX_CPU_THIS_PTR msr.apicbase);
// TLB flush is required for emulation correctness
TLB_flush(1); // don't care about performance of apic relocation
TLB_flush(); // don't care about performance of apic relocation
}
else {
BX_INFO(("WRMSR: MSR_APICBASE APIC global enable bit cleared !"));

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: smm.cc,v 1.42 2008-08-03 19:53:09 sshwarts Exp $
// $Id: smm.cc,v 1.43 2008-08-13 21:51:54 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Stanislav Shwartsman
@ -135,7 +135,7 @@ void BX_CPU_C::enter_system_management_mode(void)
BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31)
// paging mode was changed - flush TLB
TLB_flush(1); // 1 = Flush Global entries also
TLB_flush(); // Flush Global entries also
#if BX_CPU_LEVEL >= 4
BX_CPU_THIS_PTR cr4.setRegister(0);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pc_system.cc,v 1.71 2008-05-10 20:39:53 sshwarts Exp $
// $Id: pc_system.cc,v 1.72 2008-08-13 21:51:53 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -183,7 +183,7 @@ bx_bool bx_pc_system_c::get_enable_a20(void)
void bx_pc_system_c::MemoryMappingChanged(void)
{
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
BX_CPU(i)->TLB_flush(1);
BX_CPU(i)->TLB_flush();
}
void bx_pc_system_c::invlpg(bx_address addr)