summaryrefslogtreecommitdiff
path: root/src/cpu/o3/lsq_impl.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3/lsq_impl.hh')
-rw-r--r--src/cpu/o3/lsq_impl.hh22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 2c9c6eb82..e0107e36a 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -346,7 +346,29 @@ LSQ<Impl>::recvTimingResp(PacketPtr pkt)
if (pkt->isError())
DPRINTF(LSQ, "Got error packet back for address: %#X\n",
pkt->getAddr());
+
thread[pkt->req->threadId()].completeDataAccess(pkt);
+
+ if (pkt->isInvalidate()) {
+ // This response also contains an invalidate; e.g. this can be the case
+ // if cmd is ReadRespWithInvalidate.
+ //
+ // The calling order between completeDataAccess and checkSnoop matters.
+ // By calling checkSnoop after completeDataAccess, we ensure that the
+ // fault set by checkSnoop is not lost. Calling writeback (more
+ // specifically inst->completeAcc) in completeDataAccess overwrites
+ // fault, and in case this instruction requires squashing (as
+ // determined by checkSnoop), the ReExec fault set by checkSnoop would
+ // be lost otherwise.
+
+ DPRINTF(LSQ, "received invalidation with response for addr:%#x\n",
+ pkt->getAddr());
+
+ for (ThreadID tid = 0; tid < numThreads; tid++) {
+ thread[tid].checkSnoop(pkt);
+ }
+ }
+
delete pkt->req;
delete pkt;
return true;