changeset 83d5112e71dd in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=83d5112e71dd
description:
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:
src/mem/page_table.cc | 16 +++++++++-------
src/mem/page_table.hh | 21 +++++++++++++++++++++
2 files changed, 30 insertions(+), 7 deletions(-)
diffs (105 lines):
diff -r e7798df2f0a7 -r 83d5112e71dd src/mem/page_table.cc
--- a/src/mem/page_table.cc Tue Apr 23 05:07:10 2013 -0400
+++ b/src/mem/page_table.cc Tue Apr 23 09:47:52 2013 -0400
@@ -55,9 +55,9 @@
pid(_pid), _name(__name)
{
assert(isPowerOf2(pageSize));
- pTableCache[0].vaddr = 0;
- pTableCache[1].vaddr = 0;
- pTableCache[2].vaddr = 0;
+ pTableCache[0].valid = false;
+ pTableCache[1].valid = false;
+ pTableCache[2].valid = false;
}
PageTable::~PageTable()
@@ -79,6 +79,7 @@
}
pTable[vaddr] = TheISA::TlbEntry(pid, vaddr, paddr);
+ eraseCacheEntry(vaddr);
updateCache(vaddr, pTable[vaddr]);
}
}
@@ -97,6 +98,7 @@
pTable[new_vaddr] = pTable[vaddr];
pTable.erase(vaddr);
+ eraseCacheEntry(vaddr);
pTable[new_vaddr].updateVaddr(new_vaddr);
updateCache(new_vaddr, pTable[new_vaddr]);
}
@@ -111,8 +113,8 @@
for (; size > 0; size -= pageSize, vaddr += pageSize) {
assert(pTable.find(vaddr) != pTable.end());
-
pTable.erase(vaddr);
+ eraseCacheEntry(vaddr);
}
}
@@ -137,15 +139,15 @@
{
Addr page_addr = pageAlign(vaddr);
- if (pTableCache[0].vaddr == page_addr) {
+ if (pTableCache[0].valid && pTableCache[0].vaddr == page_addr) {
entry = pTableCache[0].entry;
return true;
}
- if (pTableCache[1].vaddr == page_addr) {
+ if (pTableCache[1].valid && pTableCache[1].vaddr == page_addr) {
entry = pTableCache[1].entry;
return true;
}
- if (pTableCache[2].vaddr == page_addr) {
+ if (pTableCache[2].valid && pTableCache[2].vaddr == page_addr) {
entry = pTableCache[2].entry;
return true;
}
diff -r e7798df2f0a7 -r 83d5112e71dd src/mem/page_table.hh
--- a/src/mem/page_table.hh Tue Apr 23 05:07:10 2013 -0400
+++ b/src/mem/page_table.hh Tue Apr 23 09:47:52 2013 -0400
@@ -57,6 +57,7 @@
PTable pTable;
struct cacheElement {
+ bool valid;
Addr vaddr;
TheISA::TlbEntry entry;
};
@@ -132,12 +133,32 @@
{
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);
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev