kern, arm: Dump dmesg on kernel panic/oops

Add helper functions to dump the guest kernel's dmesg buffer to a text
file in m5out. This functionality is split into two parts. First, a
dmesg dump function that can be used in other places:

void Linux::dumpDmesg(ThreadContext *, std::ostream &)

This function is used to implement two PCEvents: DmesgDumpEvent and
KernelPanic event. The only difference between the two is that the
latter produces a gem5 panic instead of a warning in addition to
dumping the kernel log.

Change-Id: I6d2af1d666ace57124089648ea906f6c787ac63c
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Gabor Dozsa <gabor.dozsa@arm.com>
This commit is contained in:
Andreas Sandberg
2016-06-20 14:39:49 +01:00
parent 60fb5e79f3
commit 37bb0d0fb3
8 changed files with 324 additions and 7 deletions

View File

@@ -98,6 +98,14 @@ class LinuxArmSystem(GenericArmSystem):
type = 'LinuxArmSystem'
cxx_header = "arch/arm/linux/system.hh"
@classmethod
def export_method_cxx_predecls(cls, code):
code('#include "arch/arm/linux/system.hh"')
@classmethod
def export_methods(cls, code):
code('''void dumpDmesg();''')
class FreebsdArmSystem(GenericArmSystem):
type = 'FreebsdArmSystem'
cxx_header = "arch/arm/freebsd/system.hh"

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 ARM Limited
* Copyright (c) 2010-2013, 2016 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -53,6 +53,7 @@
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "kern/linux/events.hh"
#include "kern/linux/helpers.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "mem/physical.hh"
#include "sim/stat_control.hh"
@@ -65,14 +66,21 @@ LinuxArmSystem::LinuxArmSystem(Params *p)
enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr)
{
const std::string dmesg_output = name() + ".dmesg";
if (p->panic_on_panic) {
kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
"panic", "Kernel panic in simulated kernel");
kernelPanicEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>(
"panic", "Kernel panic in simulated kernel", dmesg_output);
} else {
kernelPanicEvent = addKernelFuncEventOrPanic<Linux::DmesgDumpEvent>(
"panic", "Kernel panic in simulated kernel", dmesg_output);
}
if (p->panic_on_oops) {
kernelOopsEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
"oops_exit", "Kernel oops in guest");
kernelOopsEvent = addKernelFuncEventOrPanic<Linux::KernelPanicEvent>(
"oops_exit", "Kernel oops in guest", dmesg_output);
} else {
kernelOopsEvent = addKernelFuncEventOrPanic<Linux::DmesgDumpEvent>(
"oops_exit", "Kernel oops in guest", dmesg_output);
}
// With ARM udelay() is #defined to __udelay
@@ -261,6 +269,12 @@ LinuxArmSystem::mapPid(ThreadContext *tc, uint32_t pid)
}
}
void
LinuxArmSystem::dumpDmesg()
{
Linux::dumpDmesg(getThreadContext(0), std::cout);
}
/** This function is called whenever the the kernel function
* "__switch_to" is called to change running tasks.
*

View File

@@ -95,6 +95,12 @@ class LinuxArmSystem : public GenericArmSystem
* @param tc thread context that is currentyl executing */
void mapPid(ThreadContext* tc, uint32_t pid);
public: // Exported Python methods
/**
* Dump the kernel's dmesg buffer to stdout
*/
void dumpDmesg();
private:
/** Event to halt the simulator if the kernel calls panic() */
PCEvent *kernelPanicEvent;