} else {
             // response to snoop request
             DPRINTF(Cache, "processing deferred snoop...\n");
-            handleSnoop(target->pkt, blk, true, true);
+            handleSnoop(target->pkt, blk, true, true, false);
         }
 
         mshr->popTarget();
 template<class TagStore>
 void
 Cache<TagStore>::handleSnoop(PacketPtr pkt, BlkType *blk,
-                             bool is_timing, bool is_deferred)
+                             bool is_timing, bool is_deferred,
+                             bool lower_mshr_pending)
 {
     assert(pkt->isRequest());
 
     if (is_timing) {
         Packet *snoopPkt = new Packet(pkt, true);  // clear flags
         snoopPkt->setExpressSnoop();
-        if (is_deferred) {
-            snoopPkt->setDeferredSnoop();
+        if (lower_mshr_pending) {
+            snoopPkt->setLowerMSHRPending();
         }
         snoopPkt->senderState = new ForwardResponseRecord(pkt, this);
         cpuSidePort->sendTiming(snoopPkt);
 
     Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
     MSHR *mshr = mshrQueue.findMatch(blk_addr);
-    // better not be snooping a request that conflicts with something
-    // we have outstanding...
+
+    // If a lower cache has an operation on this block pending (not
+    // yet in service) on the MSHR, then the upper caches need to know
+    // about it, as this means that the pending operation logically
+    // succeeds the current snoop.  It's not sufficient to record
+    // whether the MSHR *is* in service, as this misses the window
+    // where the lower cache has completed the request and the
+    // response is on its way back up the hierarchy.
+    bool lower_mshr_pending =
+        (mshr && (!mshr->inService) || pkt->lowerMSHRPending());
+
+    // Let the MSHR itself track the snoop and decide whether we want
+    // to go ahead and do the regular cache snoop
     if (mshr && mshr->handleSnoop(pkt, order++)) {
         DPRINTF(Cache, "Deferring snoop on in-service MSHR to blk %x\n",
                 blk_addr);
         }
     }
 
-    handleSnoop(pkt, blk, true, false);
+    handleSnoop(pkt, blk, true, false, lower_mshr_pending);
 }
 
 
     }
 
     BlkType *blk = tags->findBlock(pkt->getAddr());
-    handleSnoop(pkt, blk, false, false);
+    handleSnoop(pkt, blk, false, false, false);
     return hitLatency;
 }
 
 
         Shared,
         // Special control flags
         ExpressSnoop,
-        DeferredSnoop,
+        LowerMSHRPending,  // not yet in service
         NUM_PACKET_FLAGS
     };
 
     // Special control flags
     void setExpressSnoop()      { flags[ExpressSnoop] = true; }
     bool isExpressSnoop()       { return flags[ExpressSnoop]; }
-    void setDeferredSnoop()     { flags[DeferredSnoop] = true; }
-    bool isDeferredSnoop()      { return flags[DeferredSnoop]; }
+    void setLowerMSHRPending()  { flags[LowerMSHRPending] = true; }
+    bool lowerMSHRPending()     { return flags[LowerMSHRPending]; }
 
     // Network error conditions... encapsulate them as methods since
     // their encoding keeps changing (from result field to command