[PATCH v2 2/6] sim/mips: Do not abort on a HI/LO hazard

Sebastian Huber <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
check_mf_hilo() calls sim_engine_abort() when a mfhi or mflo reads a
value which the ISA leaves UNPREDICTABLE.  The comment above the helper
states the rule correctly: the result is UNPREDICTABLE, not an error.
Reading an undefined value is not a fault, and the return value of the
helper is discarded at both call sites, so the abort is its only effect.

The abort halts the client and the run loop resumes it on the faulting
instruction, which reads the same register again and aborts again.  An
operating system may save HI and LO on interrupt entry and restore them
unchanged, so it reads them at an arbitrary instruction boundary where
the last writer is whatever the interrupted program did.  Every clock
tick landing in multiply or divide heavy code then deadlocks it.

Warn instead.

The warning repeats for every hazard.  Print it at most ten times.

Approved-By: Andrew Burgess <[email protected]>
---
 sim/mips/mips.igen | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen
index 8203d19f8c4..3b52f2df43f 100644
--- a/sim/mips/mips.igen
+++ b/sim/mips/mips.igen
@@ -410,13 +410,26 @@
       && ! (peer->mf.timestamp > history->op.timestamp
 	    && peer->mf.timestamp < peer->mt.timestamp))
     {
+      static int warning_count = 0;
+
       /* The peer has been written to since the last OP yet we have
-         not */
-      sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
-			itable[MY_INDEX].name,
-			(long) CIA,
-			(long) history->op.cia,
-			(long) peer->mt.cia);
+	 not.  The ISA makes the result of this MF UNPREDICTABLE, it does not
+	 make it an error.  An operating system may save HI and LO
+	 unconditionally on interrupt entry and restore them unchanged, so it
+	 reads whatever the interrupted program left behind.  Aborting the
+	 simulation here deadlocks such a system, since the run loop resumes at
+	 the faulting instruction and the MF is executed again.  */
+      if (warning_count < 10)
+	{
+	  ++warning_count;
+	  sim_io_eprintf (SD, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n",
+			  itable[MY_INDEX].name,
+			  (long) CIA,
+			  (long) history->op.cia,
+			  (long) peer->mt.cia);
+	  if (warning_count == 10)
+	    sim_io_eprintf (SD, "HILO: further warnings are silenced\n");
+	}
       ok = 0;
     }
   history->mf.timestamp = time;
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.