changeset 5963165c00cb in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=5963165c00cb
description:
        mem: Fix guest corruption when caches handle uncacheable accesses

        When the classic gem5 cache sees an uncacheable memory access, it used
        to ignore it or silently drop the cache line in case of a
        write. Normally, there shouldn't be any data in the cache belonging to
        an uncacheable address range. However, since some architecture models
        don't implement cache maintenance instructions, there might be some
        dirty data in the cache that is discarded when this happens. The
        reason it has mostly worked before is because such cache lines were
        most likely evicted by normal memory activity before a TLB flush was
        requested by the OS.

        Previously, the cache model would invalidate cache lines when they
        were accessed by an uncacheable write. This changeset alters this
        behavior so all uncacheable memory accesses cause a cache flush with
        an associated writeback if necessary. This is implemented by reusing
        the cache flushing machinery used when draining the cache, which
        implies that writebacks are performed using functional accesses.

diffstat:

 src/mem/cache/cache.hh      |  12 ++++++++++++
 src/mem/cache/cache_impl.hh |  40 +++++++++++++++++++++-------------------
 2 files changed, 33 insertions(+), 19 deletions(-)

diffs (86 lines):

diff -r ab47fe7f03f0 -r 5963165c00cb src/mem/cache/cache.hh
--- a/src/mem/cache/cache.hh    Mon Jan 07 13:05:46 2013 -0500
+++ b/src/mem/cache/cache.hh    Mon Jan 07 13:05:47 2013 -0500
@@ -278,6 +278,18 @@
      */
     bool invalidateVisitor(BlkType &blk);
 
+    /**
+     * Flush a cache line due to an uncacheable memory access to the
+     * line.
+     *
+     * @note This shouldn't normally happen, but we need to handle it
+     * since some architecture models don't implement cache
+     * maintenance operations. We won't even try to get a decent
+     * timing here since the line should have been flushed earlier by
+     * a cache maintenance operation.
+     */
+    void uncacheableFlush(PacketPtr pkt);
+
   public:
     /** Instantiates a basic cache object. */
     Cache(const Params *p, TagStore *tags);
diff -r ab47fe7f03f0 -r 5963165c00cb src/mem/cache/cache_impl.hh
--- a/src/mem/cache/cache_impl.hh       Mon Jan 07 13:05:46 2013 -0500
+++ b/src/mem/cache/cache_impl.hh       Mon Jan 07 13:05:47 2013 -0500
@@ -279,16 +279,7 @@
                         Cycles &lat, PacketList &writebacks)
 {
     if (pkt->req->isUncacheable()) {
-        if (pkt->req->isClearLL()) {
-            tags->clearLocks();
-        } else if (pkt->isWrite()) {
-           blk = tags->findBlock(pkt->getAddr());
-           if (blk != NULL) {
-               tags->invalidate(blk);
-               blk->invalidate();
-           }
-        }
-
+        uncacheableFlush(pkt);
         blk = NULL;
         lat = hitLatency;
         return false;
@@ -444,15 +435,7 @@
     }
 
     if (pkt->req->isUncacheable()) {
-        if (pkt->req->isClearLL()) {
-            tags->clearLocks();
-        } else if (pkt->isWrite()) {
-            BlkType *blk = tags->findBlock(pkt->getAddr());
-            if (blk != NULL) {
-                tags->invalidate(blk);
-                blk->invalidate();
-            }
-        }
+        uncacheableFlush(pkt);
 
         // writes go in write buffer, reads use MSHR
         if (pkt->isWrite() && !pkt->isRead()) {
@@ -1104,6 +1087,25 @@
 }
 
 template<class TagStore>
+void
+Cache<TagStore>::uncacheableFlush(PacketPtr pkt)
+{
+    DPRINTF(Cache, "%s%s %x uncacheable\n", pkt->cmdString(),
+            pkt->req->isInstFetch() ? " (ifetch)" : "",
+            pkt->getAddr());
+
+    if (pkt->req->isClearLL())
+        tags->clearLocks();
+
+    BlkType *blk(tags->findBlock(pkt->getAddr()));
+    if (blk) {
+        writebackVisitor(*blk);
+        invalidateVisitor(*blk);
+    }
+}
+
+
+template<class TagStore>
 typename Cache<TagStore>::BlkType*
 Cache<TagStore>::allocateBlock(Addr addr, PacketList &writebacks)
 {
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to