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

Reply via email to