cpu: Fix O3 uncacheable load that is replayed but misses the TLB
authorAli Saidi <Ali.Saidi@ARM.com>
Thu, 17 Oct 2013 15:20:45 +0000 (10:20 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Thu, 17 Oct 2013 15:20:45 +0000 (10:20 -0500)
This change fixes an issue in the O3 CPU where an uncachable instruction
is attempted to be executed before it reaches the head of the ROB. It is
determined to be uncacheable, and is replayed, but a PanicFault is attached
to the instruction to make sure that it is properly executed before
committing. If the TLB entry it was using is replaced in the interveaning
time, the TLB returns a delayed translation when the load is replayed at
the head of the ROB, however the LSQ code can't differntiate between the
old fault and the new one. If the translation isn't complete it can't
be faulting, so clear the fault.

src/cpu/base_dyn_inst.hh

index 6aecd32dc7d36d06fec1647bfabc82ae0a6b36aa..b7b0768203d585fb98fedb02a1a102c0215626c3 100644 (file)
@@ -1009,8 +1009,16 @@ BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow,
         // One translation if the request isn't split.
         DataTranslation<BaseDynInstPtr> *trans =
             new DataTranslation<BaseDynInstPtr>(this, state);
+
         cpu->dtb->translateTiming(req, thread->getTC(), trans, mode);
+
         if (!translationCompleted()) {
+            // The translation isn't yet complete, so we can't possibly have a
+            // fault. Overwrite any existing fault we might have from a previous
+            // execution of this instruction (e.g. an uncachable load that
+            // couldn't execute because it wasn't at the head of the ROB).
+            fault = NoFault;
+
             // Save memory requests.
             savedReq = state->mainReq;
             savedSreqLow = state->sreqLow;
@@ -1028,7 +1036,14 @@ BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow,
 
         cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode);
         cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode);
+
         if (!translationCompleted()) {
+            // The translation isn't yet complete, so we can't possibly have a
+            // fault. Overwrite any existing fault we might have from a previous
+            // execution of this instruction (e.g. an uncachable load that
+            // couldn't execute because it wasn't at the head of the ROB).
+            fault = NoFault;
+
             // Save memory requests.
             savedReq = state->mainReq;
             savedSreqLow = state->sreqLow;