summaryrefslogtreecommitdiff
path: root/src/mem/page_table.hh
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga+gem5@gmail.com>2013-04-23 09:47:52 -0400
committerMitch Hayenga <mitch.hayenga+gem5@gmail.com>2013-04-23 09:47:52 -0400
commitb222ba2fd32c5ac9c91cfab518382761cac5b2c7 (patch)
tree09e3dddac2413aa7cf6ea4b58faab9a7bd4708d4 /src/mem/page_table.hh
parent3e35fa5dcc8af49f652a20595ce2470b5a116ddc (diff)
downloadgem5-b222ba2fd32c5ac9c91cfab518382761cac5b2c7.tar.xz
sim: Fix two bugs relating to software caching of PageTable entries.
The existing implementation can read uninitialized data or stale information from the cached PageTable entries. 1) Add a valid bit for the cache entries. Simply using zero for the virtual address to signify invalid entries is not sufficient. Speculative, wrong-path accesses frequently access page zero. The current implementation would return a uninitialized TLB entry when address zero was accessed and the PageTable cache entry was invalid. 2) When unmapping/mapping/remaping a page, invalidate the corresponding PageTable cache entry if one already exists.
Diffstat (limited to 'src/mem/page_table.hh')
-rw-r--r--src/mem/page_table.hh21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh
index b1b5227be..ce3bfa5e1 100644
--- a/src/mem/page_table.hh
+++ b/src/mem/page_table.hh
@@ -57,6 +57,7 @@ class PageTable
PTable pTable;
struct cacheElement {
+ bool valid;
Addr vaddr;
TheISA::TlbEntry entry;
};
@@ -132,12 +133,32 @@ class PageTable
{
pTableCache[2].entry = pTableCache[1].entry;
pTableCache[2].vaddr = pTableCache[1].vaddr;
+ pTableCache[2].valid = pTableCache[1].valid;
+
pTableCache[1].entry = pTableCache[0].entry;
pTableCache[1].vaddr = pTableCache[0].vaddr;
+ pTableCache[1].valid = pTableCache[0].valid;
+
pTableCache[0].entry = entry;
pTableCache[0].vaddr = vaddr;
+ pTableCache[0].valid = true;
}
+ /**
+ * Erase an entry from the page table cache.
+ * @param vaddr virtual address (page aligned) to check
+ */
+ inline void eraseCacheEntry(Addr vaddr)
+ {
+ // Invalidate cached entries if necessary
+ if (pTableCache[0].valid && pTableCache[0].vaddr == vaddr) {
+ pTableCache[0].valid = false;
+ } else if (pTableCache[1].valid && pTableCache[1].vaddr == vaddr) {
+ pTableCache[1].valid = false;
+ } else if (pTableCache[2].valid && pTableCache[2].vaddr == vaddr) {
+ pTableCache[2].valid = false;
+ }
+ }
void serialize(std::ostream &os);