arch-power: Add support for trapping user faults
This adds support for trapping into GDB when user-mode
faults such as those pertaining to alignment (SIGBUS),
traps (SIGTRAP) and unimplemented opcodes (SIGILL) are
encountered.
Change-Id: Ieb557abd4173b5acb4be6f0c30964aea1eba71a5
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47359
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Boris Shingarov <shingarov@labware.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript
index 720455c..52a607d 100644
--- a/src/arch/power/SConscript
+++ b/src/arch/power/SConscript
@@ -34,6 +34,7 @@
# Scons bug id: 2006 M5 Bug id: 308
Dir('isa/formats')
Source('decoder.cc')
+ Source('faults.cc')
Source('insts/branch.cc')
Source('insts/mem.cc')
Source('insts/integer.cc')
diff --git a/src/arch/power/faults.cc b/src/arch/power/faults.cc
new file mode 100644
index 0000000..3b8851e
--- /dev/null
+++ b/src/arch/power/faults.cc
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021 IBM Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "arch/power/faults.hh"
+
+#include <csignal>
+
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+
+namespace gem5
+{
+
+namespace PowerISA
+{
+
+void
+UnimplementedOpcodeFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
+{
+ panic_if(tc->getSystemPtr()->trapToGdb(SIGILL, tc->contextId()),
+ "Unimplemented opcode encountered at virtual address %#x\n",
+ tc->pcState().pc());
+}
+
+void
+AlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
+{
+ panic_if(!tc->getSystemPtr()->trapToGdb(SIGBUS, tc->contextId()),
+ "Alignment fault when accessing virtual address %#x\n", vaddr);
+}
+
+void
+TrapFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
+{
+ panic_if(tc->getSystemPtr()->trapToGdb(SIGTRAP, tc->contextId()),
+ "Trap encountered at virtual address %#x\n",
+ tc->pcState().pc());
+}
+
+} // namespace PowerISA
+
+} // namespace gem5
diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh
index edfcc8f..03eeee7 100644
--- a/src/arch/power/faults.hh
+++ b/src/arch/power/faults.hh
@@ -63,6 +63,9 @@
: PowerFault("Unimplemented Opcode")
{
}
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ nullStaticInstPtr) override;
};
@@ -78,11 +81,16 @@
class AlignmentFault : public PowerFault
{
+ private:
+ Addr vaddr;
public:
- AlignmentFault()
- : PowerFault("Alignment")
+ AlignmentFault(Addr va)
+ : PowerFault("Alignment"), vaddr(va)
{
}
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ nullStaticInstPtr) override;
};
@@ -93,6 +101,9 @@
: PowerFault("Trap")
{
}
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ nullStaticInstPtr) override;
};
} // namespace PowerISA
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
index 9c2804d..d54a124 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -575,7 +575,6 @@
code = 'int64_t src1 = ' + src1 + ';\n'
code += 'int64_t src2 = ' + src2 + ';\n'
code += 'if (checkTrap(src1, src2)) {\n'
- code += ' panic("trap generated at %#x", xc->pcState().pc());\n'
code += ' return std::make_shared<TrapFault>();\n'
code += '}\n'
@@ -590,7 +589,6 @@
# Add code to set up variables and check for a trap
code = 'int64_t src = ' + src + ';\n'
code += 'if (checkTrap(src, si)) {\n'
- code += ' panic("trap generated at %#x", xc->pcState().pc());\n'
code += ' return std::make_shared<TrapFault>();\n'
code += '}\n'
diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa
index 31290d5..921700b 100644
--- a/src/arch/power/isa/formats/unknown.isa
+++ b/src/arch/power/isa/formats/unknown.isa
@@ -71,9 +71,9 @@
Fault
Unknown::execute(ExecContext *xc, Trace::InstRecord *traceData) const
{
- panic("attempt to execute unknown instruction at %#x"
- "(inst 0x%08x, opcode 0x%x, binary: %s)",
- xc->pcState().pc(), machInst, PO, inst2string(machInst));
+ inform("attempt to execute unknown instruction at %#x"
+ "(inst 0x%08x, opcode 0x%x, binary: %s)",
+ xc->pcState().pc(), machInst, PO, inst2string(machInst));
return std::make_shared<UnimplementedOpcodeFault>();
}
}};
diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc
index f559d59..4bca6f0 100644
--- a/src/arch/power/tlb.cc
+++ b/src/arch/power/tlb.cc
@@ -218,11 +218,13 @@
Fault
TLB::translateInst(const RequestPtr &req, ThreadContext *tc)
{
+ Addr vaddr = req->getVaddr();
+
// Instruction accesses must be word-aligned
- if (req->getVaddr() & 0x3) {
- DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", req->getVaddr(),
+ if (vaddr & 0x3) {
+ DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", vaddr,
req->getSize());
- return std::make_shared<AlignmentFault>();
+ return std::make_shared<AlignmentFault>(vaddr);
}
return tc->getProcessPtr()->pTable->translate(req);