arm: Enable support for triggering a sim panic on kernel panics
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 22 Apr 2013 17:20:31 +0000 (13:20 -0400)
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>
Mon, 22 Apr 2013 17:20:31 +0000 (13:20 -0400)
Add the options 'panic_on_panic' and 'panic_on_oops' to the
LinuxArmSystem SimObject. When these option are enabled, the simulator
panics when the guest kernel panics or oopses. Enable panic on panic
and panic on oops in ARM-based test cases.

src/arch/arm/ArmSystem.py
src/arch/arm/linux/system.cc
src/arch/arm/linux/system.hh
src/cpu/pc_event.cc
src/cpu/pc_event.hh
tests/configs/arm_generic.py

index 763b043dce31c92d21a5141300c93389bbac8c6b..b48c2a29de814def99ece8b6a6611f99f819074d 100644 (file)
@@ -68,3 +68,8 @@ class LinuxArmSystem(ArmSystem):
     early_kernel_symbols = Param.Bool(False,
         "enable early kernel symbol tables before MMU")
     enable_context_switch_stats_dump = Param.Bool(False, "enable stats/task info dumping at context switch boundaries")
+
+    panic_on_panic = Param.Bool(False, "Trigger a gem5 panic if the " \
+                                    "guest kernel panics")
+    panic_on_oops = Param.Bool(False, "Trigger a gem5 panic if the " \
+                                   "guest kernel oopses")
index de4c27d8b25058fbf0f8c90e1ba8d5650ef19800..e714cc9134a721358a7c5ee52da6c948b8cafe64 100644 (file)
@@ -62,11 +62,22 @@ using namespace Linux;
 
 LinuxArmSystem::LinuxArmSystem(Params *p)
     : ArmSystem(p),
-      enableContextSwitchStatsDump(p->enable_context_switch_stats_dump)
+      enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
+      kernelPanicEvent(NULL), kernelOopsEvent(NULL)
 {
+    if (p->panic_on_panic) {
+        kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
+            "panic", "Kernel panic in simulated kernel");
+    } else {
 #ifndef NDEBUG
-    kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
+        kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
 #endif
+    }
+
+    if (p->panic_on_oops) {
+        kernelOopsEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
+            "oops_exit", "Kernel oops in guest");
+    }
 
     // With ARM udelay() is #defined to __udelay
     uDelaySkipEvent = addKernelFuncEventOrPanic<UDelayEvent>(
index feed8cfaa537e71f64e31af22b67dd186db7949d..008c644292ba37b5ecf647631dae6f73fc7161ef 100644 (file)
@@ -98,10 +98,12 @@ class LinuxArmSystem : public ArmSystem
     void mapPid(ThreadContext* tc, uint32_t pid);
 
   private:
-#ifndef NDEBUG
     /** Event to halt the simulator if the kernel calls panic()  */
-    BreakPCEvent *kernelPanicEvent;
-#endif
+    PCEvent *kernelPanicEvent;
+
+    /** Event to halt the simulator if the kernel calls oopses  */
+    PCEvent *kernelOopsEvent;
+
     /**
      * PC based event to skip udelay(<time>) calls and quiesce the
      * processor for the appropriate amount of time. This is not functionally
index c957fe4d5521322e058659182f2ea57225b969a6..837b17e34f9275fd6f6194548813070f2d3c5633 100644 (file)
@@ -158,3 +158,15 @@ sched_break_pc(Addr addr)
     }
 
 }
+
+PanicPCEvent::PanicPCEvent(PCEventQueue *q, const std::string &desc, Addr pc)
+    : PCEvent(q, desc, pc)
+{
+}
+
+void
+PanicPCEvent::process(ThreadContext *tc)
+{
+    StringWrap name(tc->getCpuPtr()->name() + ".panic_event");
+    panic(descr());
+}
index c73fc3c5af667cc8080c7d5d605c3eea012ddc7a..11fce2ca04b49f638d7e86a45cc4fe1c6936edf4 100644 (file)
@@ -146,4 +146,11 @@ void sched_break_pc_sys(System *sys, Addr addr);
 
 void sched_break_pc(Addr addr);
 
+class PanicPCEvent : public PCEvent
+{
+  public:
+    PanicPCEvent(PCEventQueue *q, const std::string &desc, Addr pc);
+    virtual void process(ThreadContext *tc);
+};
+
 #endif // __PC_EVENT_HH__
index 95f9b8bd1b21865f6b241436e2589ba09fa83bef..1b0e8ee8b6e16dfbf05cb66cc347c767187525e9 100644 (file)
@@ -62,6 +62,13 @@ class LinuxArmSystemBuilder(object):
         system = FSConfig.makeArmSystem(self.mem_mode,
                                         self.machine_type,
                                         None, False)
+
+        # We typically want the simulator to panic if the kernel
+        # panics or oopses. This prevents the simulator from running
+        # an obviously failed test case until the end of time.
+        system.panic_on_panic = True
+        system.panic_on_oops = True
+
         self.init_system(system)
         return system