From f019d9f866cb5bfd639365c13f325d128f745f7f Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Tue, 29 Jun 2021 13:17:35 +0530 Subject: [PATCH] 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/47359 Reviewed-by: Boris Shingarov Maintainer: Boris Shingarov Tested-by: kokoro --- src/arch/power/SConscript | 1 + src/arch/power/faults.cc | 67 ++++++++++++++++++++++++++ src/arch/power/faults.hh | 15 +++++- src/arch/power/isa/formats/integer.isa | 2 - src/arch/power/isa/formats/unknown.isa | 6 +-- src/arch/power/tlb.cc | 8 +-- 6 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/arch/power/faults.cc diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript index 720455c588..52a607d1b6 100644 --- a/src/arch/power/SConscript +++ b/src/arch/power/SConscript @@ -34,6 +34,7 @@ if env['TARGET_ISA'] == 'power': # 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 0000000000..3b8851e3b3 --- /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 + +#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 edfcc8fe2e..03eeee7d1b 100644 --- a/src/arch/power/faults.hh +++ b/src/arch/power/faults.hh @@ -63,6 +63,9 @@ class UnimplementedOpcodeFault : public PowerFault : PowerFault("Unimplemented Opcode") { } + + void invoke(ThreadContext *tc, const StaticInstPtr &inst = + nullStaticInstPtr) override; }; @@ -78,11 +81,16 @@ class MachineCheckFault : public PowerFault 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 @@ class TrapFault : public PowerFault : 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 9c2804d3e9..d54a124f84 100644 --- a/src/arch/power/isa/formats/integer.isa +++ b/src/arch/power/isa/formats/integer.isa @@ -575,7 +575,6 @@ def format IntTrapOp(src1, src2, inst_flags = []) {{ 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();\n' code += '}\n' @@ -590,7 +589,6 @@ def format IntImmTrapOp(src, inst_flags = []) {{ # 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();\n' code += '}\n' diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa index 31290d54cc..921700b8c5 100644 --- a/src/arch/power/isa/formats/unknown.isa +++ b/src/arch/power/isa/formats/unknown.isa @@ -71,9 +71,9 @@ output exec {{ 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(); } }}; diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc index f559d596b2..4bca6f063c 100644 --- a/src/arch/power/tlb.cc +++ b/src/arch/power/tlb.cc @@ -218,11 +218,13 @@ TLB::unserialize(CheckpointIn &cp) 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(); + return std::make_shared(vaddr); } return tc->getProcessPtr()->pTable->translate(req);