diff options
author | Mitch Hayenga <mitch.hayenga+gem5@gmail.com> | 2013-04-23 09:47:52 -0400 |
---|---|---|
committer | Mitch Hayenga <mitch.hayenga+gem5@gmail.com> | 2013-04-23 09:47:52 -0400 |
commit | b222ba2fd32c5ac9c91cfab518382761cac5b2c7 (patch) | |
tree | 09e3dddac2413aa7cf6ea4b58faab9a7bd4708d4 /src/mem/page_table.hh | |
parent | 3e35fa5dcc8af49f652a20595ce2470b5a116ddc (diff) | |
download | gem5-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.hh | 21 |
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); |