sim: Rework the Linux Kernel exit events (#639)
This patch reworks the Linux Kernel panic and oops events. The code has been re-factored to provide re-usable events that can be applied to all ISAs from the base `KernelWorkload` `SimObject`. At the moment they are installed for the Arm workloads. This update also provides more configuration options that can be specified using the new `KernelPanicOopsBehaviour` enum. The options are applied to the Kernel Workload parameters `on_panic` and `on_oops` which are available to all subclasses of `KernelWorkload`. The main rationale for this reworking is to add the option to cleanly exit the simulation after dumping the Dmesg buffer. Without this option, the simulation would continue running after a Kernel panic. If system components (e.g. a system timer) keep the event queue alive, this causes the simulation to run slowly to the maximum allowed tick.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013, 2016, 2020 ARM Limited
|
||||
* Copyright (c) 2010-2013, 2016, 2020, 2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -228,21 +228,22 @@ FsLinux::startup()
|
||||
}
|
||||
}
|
||||
|
||||
const std::string dmesg_output = name() + ".dmesg";
|
||||
if (params().panic_on_panic) {
|
||||
kernelPanic = addKernelFuncEventOrPanic<linux::KernelPanic>(
|
||||
"panic", "Kernel panic in simulated kernel", dmesg_output);
|
||||
} else {
|
||||
kernelPanic = addKernelFuncEventOrPanic<linux::DmesgDump>(
|
||||
"panic", "Kernel panic in simulated kernel", dmesg_output);
|
||||
const std::string dmesg_output_fname = name() + ".dmesg";
|
||||
|
||||
kernelPanic = addKernelFuncEvent<linux::PanicOrOopsEvent>(
|
||||
"panic", "Kernel panic in simulated kernel",
|
||||
dmesg_output_fname, params().on_panic);
|
||||
if (kernelPanic == nullptr) {
|
||||
warn("Could not add Kernel Panic event handler. "
|
||||
"`panic` symbol not found.");
|
||||
}
|
||||
|
||||
if (params().panic_on_oops) {
|
||||
kernelOops = addKernelFuncEventOrPanic<linux::KernelPanic>(
|
||||
"oops_exit", "Kernel oops in guest", dmesg_output);
|
||||
} else {
|
||||
kernelOops = addKernelFuncEventOrPanic<linux::DmesgDump>(
|
||||
"oops_exit", "Kernel oops in guest", dmesg_output);
|
||||
kernelOops = addKernelFuncEvent<linux::PanicOrOopsEvent>(
|
||||
"oops_exit", "Kernel oops in guest",
|
||||
dmesg_output_fname, params().on_oops);
|
||||
if (kernelOops == nullptr) {
|
||||
warn("Could not add Kernel Oops event handler. "
|
||||
"`oops_exit` symbol not found.");
|
||||
}
|
||||
|
||||
// With ARM udelay() is #defined to __udelay
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2016 ARM Limited
|
||||
* Copyright (c) 2011, 2016, 2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "kern/linux/helpers.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "sim/core.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
namespace gem5
|
||||
@@ -58,25 +59,22 @@ namespace linux
|
||||
{
|
||||
|
||||
void
|
||||
DmesgDump::process(ThreadContext *tc)
|
||||
PanicOrOopsEvent::process(ThreadContext *tc)
|
||||
{
|
||||
inform("Dumping kernel dmesg buffer to %s...\n", fname);
|
||||
OutputStream *os = simout.create(fname);
|
||||
dumpDmesg(tc, *os->stream());
|
||||
simout.close(os);
|
||||
|
||||
warn(descr());
|
||||
}
|
||||
|
||||
void
|
||||
KernelPanic::process(ThreadContext *tc)
|
||||
{
|
||||
inform("Dumping kernel dmesg buffer to %s...\n", fname);
|
||||
OutputStream *os = simout.create(fname);
|
||||
dumpDmesg(tc, *os->stream());
|
||||
simout.close(os);
|
||||
if (behaviour != KernelPanicOopsBehaviour::Continue) {
|
||||
inform("Dumping kernel dmesg buffer to %s...\n", fname);
|
||||
OutputStream *os = simout.create(fname);
|
||||
dumpDmesg(tc, *os->stream());
|
||||
simout.close(os);
|
||||
}
|
||||
|
||||
panic(descr());
|
||||
if (behaviour == KernelPanicOopsBehaviour::DumpDmesgAndExit) {
|
||||
exitSimLoop(descr(), static_cast<int>(1), curTick(), false);
|
||||
} else if (behaviour == KernelPanicOopsBehaviour::DumpDmesgAndPanic) {
|
||||
panic(descr());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
* Copyright (c) 2016, 2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "base/compiler.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "debug/DebugPrintf.hh"
|
||||
#include "enums/KernelPanicOopsBehaviour.hh"
|
||||
#include "kern/linux/printk.hh"
|
||||
#include "kern/system_events.hh"
|
||||
#include "mem/se_translating_port_proxy.hh"
|
||||
@@ -83,43 +84,25 @@ class DebugPrintk : public Base
|
||||
};
|
||||
|
||||
/**
|
||||
* Dump the guest kernel's dmesg buffer to a file in gem5's output
|
||||
* directory and print a warning.
|
||||
* Specify what to do on a Linux Kernel Panic or Oops.
|
||||
*
|
||||
* @warn This event uses linux::dumpDmesg() and comes with the same
|
||||
* @warn This event may use linux::dumpDmesg() and comes with the same
|
||||
* limitations. Most importantly, the kernel's address mappings must
|
||||
* be available to the translating proxy.
|
||||
*/
|
||||
class DmesgDump : public PCEvent
|
||||
class PanicOrOopsEvent : public PCEvent
|
||||
{
|
||||
protected:
|
||||
std::string fname;
|
||||
KernelPanicOopsBehaviour behaviour;
|
||||
|
||||
public:
|
||||
DmesgDump(PCEventScope *s, const std::string &desc, Addr addr,
|
||||
const std::string &_fname) :
|
||||
PCEvent(s, desc, addr), fname(_fname)
|
||||
{}
|
||||
void process(ThreadContext *tc) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dump the guest kernel's dmesg buffer to a file in gem5's output
|
||||
* directory and panic.
|
||||
*
|
||||
* @warn This event uses linux::dumpDmesg() and comes with the same
|
||||
* limitations. Most importantly, the kernel's address mappings must
|
||||
* be available to the translating proxy.
|
||||
*/
|
||||
class KernelPanic : public PCEvent
|
||||
{
|
||||
protected:
|
||||
std::string fname;
|
||||
|
||||
public:
|
||||
KernelPanic(PCEventScope *s, const std::string &desc, Addr addr,
|
||||
const std::string &_fname) :
|
||||
PCEvent(s, desc, addr), fname(_fname)
|
||||
PanicOrOopsEvent(PCEventScope *s, const std::string &desc, Addr addr,
|
||||
const std::string &_fname,
|
||||
const KernelPanicOopsBehaviour _behaviour)
|
||||
: PCEvent(s, desc, addr)
|
||||
, fname(_fname)
|
||||
, behaviour(_behaviour)
|
||||
{}
|
||||
void process(ThreadContext *tc) override;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# -*- mode:python -*-
|
||||
|
||||
# Copyright (c) 2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Copyright (c) 2006 The Regents of The University of Michigan
|
||||
# All rights reserved.
|
||||
#
|
||||
@@ -31,7 +42,8 @@ Import('*')
|
||||
SimObject('ClockedObject.py', sim_objects=['ClockedObject'])
|
||||
SimObject('TickedObject.py', sim_objects=['TickedObject'])
|
||||
SimObject('Workload.py', sim_objects=[
|
||||
'Workload', 'StubWorkload', 'KernelWorkload', 'SEWorkload'])
|
||||
'Workload', 'StubWorkload', 'KernelWorkload', 'SEWorkload'],
|
||||
enums=['KernelPanicOopsBehaviour'])
|
||||
SimObject('Root.py', sim_objects=['Root'])
|
||||
SimObject('ClockDomain.py', sim_objects=[
|
||||
'ClockDomain', 'SrcClockDomain', 'DerivedClockDomain'])
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
# Copyright (c) 2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Copyright 2019 Google Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -62,6 +74,16 @@ class StubWorkload(Workload):
|
||||
)
|
||||
|
||||
|
||||
class KernelPanicOopsBehaviour(ScopedEnum):
|
||||
"Define what gem5 should do after a Kernel Panic or Oops."
|
||||
vals = [
|
||||
"Continue",
|
||||
"DumpDmesgAndContinue",
|
||||
"DumpDmesgAndExit",
|
||||
"DumpDmesgAndPanic",
|
||||
]
|
||||
|
||||
|
||||
class KernelWorkload(Workload):
|
||||
type = "KernelWorkload"
|
||||
cxx_header = "sim/kernel_workload.hh"
|
||||
@@ -86,6 +108,18 @@ class KernelWorkload(Workload):
|
||||
|
||||
command_line = Param.String("a", "boot flags to pass to the kernel")
|
||||
|
||||
on_panic = Param.KernelPanicOopsBehaviour(
|
||||
"DumpDmesgAndExit",
|
||||
"Define how gem5 should behave after a Linux Kernel Panic. "
|
||||
"Handler might not be implemented for all architectures.",
|
||||
)
|
||||
|
||||
on_oops = Param.KernelPanicOopsBehaviour(
|
||||
"DumpDmesgAndExit",
|
||||
"Define how gem5 should behave after a Linux Kernel Oops. "
|
||||
"Handler might not be implemented for all architectures.",
|
||||
)
|
||||
|
||||
|
||||
class SEWorkloadMeta(type(Workload)):
|
||||
all_se_workload_classes = []
|
||||
|
||||
Reference in New Issue
Block a user