summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2012-04-24 00:48:41 -0700
committerGabe Black <gblack@eecs.umich.edu>2012-04-24 00:48:41 -0700
commit64bf90dca3b050591386cfc09121a54733f57706 (patch)
tree4a065a40c0f2cbcefc9d4f6f524e7b56b20da9f1
parent74ca8a3cd023bce0e919d09b494ee1e6c672a2a2 (diff)
downloadgem5-64bf90dca3b050591386cfc09121a54733f57706.tar.xz
X86: Clear out duplicate TLB entries when adding a new one.
It's possible for two page table walks to overlap which will go in the same place in the TLB's trie. They would land on top of each other, so this change adds some code which detects if an address already matches an entry and if so throws away the new one.
-rw-r--r--src/arch/x86/tlb.cc11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index caa3efc1e..8dad84dc4 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -98,11 +98,16 @@ TLB::evictLRU()
TlbEntry *
TLB::insert(Addr vpn, TlbEntry &entry)
{
- //TODO Deal with conflicting entries
+ // If somebody beat us to it, just use that existing entry.
+ TlbEntry *newEntry = trie.lookup(vpn);
+ if (newEntry) {
+ assert(newEntry->vaddr = vpn);
+ return newEntry;
+ }
- TlbEntry *newEntry = NULL;
if (freeList.empty())
evictLRU();
+
newEntry = freeList.front();
freeList.pop_front();
@@ -110,7 +115,7 @@ TLB::insert(Addr vpn, TlbEntry &entry)
newEntry->lruSeq = nextSeq();
newEntry->vaddr = vpn;
newEntry->trieHandle =
- trie.insert(vpn, TlbEntryTrie::MaxBits - entry.logBytes, newEntry);
+ trie.insert(vpn, TlbEntryTrie::MaxBits - entry.logBytes, newEntry);
return newEntry;
}