From 0ad5d1edc5e16e6d47718c94d464bde8e6faaae9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 23 Aug 2020 01:33:22 -0700 Subject: [PATCH] arch,cpu,sim: Route system calls through the workload. System calls should now be requested from the workload directly and not routed through ExecContext or ThreadContext interfaces. That removes a major special case for SE mode from those interfaces. For now, when the SE workload gets a request for a system call, it dispatches it to the appropriate Process object. In the future, the ISA specific Workload subclasses will be responsible for handling system calls and not the Process classes. For simplicity, the Workload syscall() method is defined in the base class but will panic everywhere except when SEWorkload overrides it. In the future, this mechanism will turn into a way to request generic services from the workload which are not necessarily system calls. For instance, it could be a way to request handling of a page fault without having to have another PseudoInst just for that purpose. Change-Id: I18d36d64c54adf4f4f17a62e7e006ff2fc0b22f1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33282 Reviewed-by: Matthew Poremba Maintainer: Gabe Black Tested-by: kokoro --- src/arch/arm/faults.cc | 2 +- src/arch/riscv/faults.cc | 2 +- src/arch/sparc/linux/process.cc | 4 ++-- src/cpu/checker/cpu.hh | 3 --- src/cpu/checker/thread_context.hh | 3 --- src/cpu/exec_context.hh | 12 ------------ src/cpu/minor/exec_context.hh | 2 -- src/cpu/o3/cpu.cc | 20 -------------------- src/cpu/o3/cpu.hh | 5 ----- src/cpu/o3/dyn_inst.hh | 3 --- src/cpu/o3/dyn_inst_impl.hh | 15 --------------- src/cpu/o3/thread_context.hh | 7 ------- src/cpu/o3/thread_state.hh | 3 --- src/cpu/simple/exec_context.hh | 5 ----- src/cpu/simple_thread.hh | 2 -- src/cpu/thread_context.hh | 2 -- src/sim/faults.cc | 2 +- src/sim/pseudo_inst.cc | 2 +- src/sim/se_workload.cc | 7 +++++++ src/sim/se_workload.hh | 2 ++ src/sim/workload.hh | 6 ++++++ 21 files changed, 21 insertions(+), 88 deletions(-) diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 56e1814c6..c590d78a5 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -865,7 +865,7 @@ SupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst) // As of now, there isn't a 32 bit thumb version of this instruction. assert(!machInst.bigThumb); - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); // Advance the PC since that won't happen automatically. PCState pc = tc->pcState(); diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc index 7a1c7bd8c..ac4c5823e 100644 --- a/src/arch/riscv/faults.cc +++ b/src/arch/riscv/faults.cc @@ -194,7 +194,7 @@ BreakpointFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) void SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) { - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); } } // namespace RiscvISA diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index 79bbaeed2..ce051ba95 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -92,7 +92,7 @@ Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc) { switch (trapNum) { case 0x10: //Linux 32 bit syscall trap - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); break; default: SparcProcess::handleTrap(trapNum, tc); @@ -129,7 +129,7 @@ Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc) switch (trapNum) { // case 0x10: // Linux 32 bit syscall trap case 0x6d: // Linux 64 bit syscall trap - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); break; case 0x6e: // Linux 64 bit getcontext trap getContext(tc); diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index f2395d7b7..f5d783492 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -610,9 +610,6 @@ class CheckerCPU : public BaseCPU, public ExecContext ///////////////////////////////////////////////////// void wakeup(ThreadID tid) override { } - // Assume that the normal CPU's call to syscall was successful. - // The checker's state would have already been updated by the syscall. - void syscall() override { } void handleError() diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index b5a974bce..d07de6251 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -171,9 +171,6 @@ class CheckerThreadContext : public ThreadContext actualTC->connectMemPorts(tc); } - /** Executes a syscall in SE mode. */ - void syscall() override { return actualTC->syscall(); } - Status status() const override { return actualTC->status(); } void diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index cfef3c3c9..b1cdbd89c 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -300,18 +300,6 @@ class ExecContext { /** @} */ - /** - * @{ - * @name SysCall Emulation Interfaces - */ - - /** - * Executes a syscall. - */ - virtual void syscall() = 0; - - /** @} */ - /** Returns a pointer to the ThreadContext. */ virtual ThreadContext *tcBase() const = 0; diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 81675e604..58301a070 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -419,8 +419,6 @@ class ExecContext : public ::ExecContext return thread.setMiscReg(reg.index(), val); } - void syscall() override { thread.syscall(); } - ThreadContext *tcBase() const override { return thread.getTC(); } /* @todo, should make stCondFailures persistent somewhere */ diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 01938f141..11fac25a0 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -912,26 +912,6 @@ FullO3CPU::trap(const Fault &fault, ThreadID tid, fault->invoke(this->threadContexts[tid], inst); } -template -void -FullO3CPU::syscall(ThreadID tid) -{ - DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid); - - DPRINTF(Activity,"Activity: syscall() called.\n"); - - // Temporarily increase this by one to account for the syscall - // instruction. - ++(this->thread[tid]->funcExeInst); - - // Execute the actual syscall. - this->thread[tid]->syscall(); - - // Decrease funcExeInst by one as the normal commit will handle - // incrementing it. - --(this->thread[tid]->funcExeInst); -} - template void FullO3CPU::serializeThread(CheckpointOut &cp, ThreadID tid) const diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 04472752c..200d34398 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -276,11 +276,6 @@ class FullO3CPU : public BaseO3CPU void exitThreads(); public: - /** Executes a syscall. - * @todo: Determine if this needs to be virtual. - */ - void syscall(ThreadID tid); - /** Starts draining the CPU's pipeline of all instructions in * order to stop all memory accesses. */ DrainState drain() override; diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 5f2a5886b..8172b9aa0 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -248,9 +248,6 @@ class BaseO3DynInst : public BaseDynInst /** Traps to handle specified fault. */ void trap(const Fault &fault); - /** Emulates a syscall. */ - void syscall() override; - public: // The register accessor methods provide the index of the diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 8a6a434a0..6c6625c43 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -187,19 +187,4 @@ BaseO3DynInst::trap(const Fault &fault) this->cpu->trap(fault, this->threadNumber, this->staticInst); } -template -void -BaseO3DynInst::syscall() -{ - // HACK: check CPU's nextPC before and after syscall. If it - // changes, update this instruction's nextPC because the syscall - // must have changed the nextPC. - TheISA::PCState curPC = this->cpu->pcState(this->threadNumber); - this->cpu->syscall(this->threadNumber); - TheISA::PCState newPC = this->cpu->pcState(this->threadNumber); - if (!(curPC == newPC)) { - this->pcState(newPC); - } -} - #endif//__CPU_O3_DYN_INST_IMPL_HH__ diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index b3eba134d..8d6edbf8d 100644 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -419,13 +419,6 @@ class O3ThreadContext : public ThreadContext thread->storeCondFailures = sc_failures; } - /** Executes a syscall in SE mode. */ - void - syscall() override - { - return cpu->syscall(thread->threadId()); - } - /** Reads the funcExeInst counter. */ Counter readFuncExeInst() const override { return thread->funcExeInst; } diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 32268325a..285adeab1 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -128,9 +128,6 @@ struct O3ThreadState : public ThreadState { /** Returns a pointer to the TC of this thread. */ ThreadContext *getTC() { return tc; } - - /** Handles the syscall. */ - void syscall() { process->syscall(tc); } }; #endif // __CPU_O3_THREAD_STATE_HH__ diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index 2b2afd282..fbd2d96e1 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -496,11 +496,6 @@ class SimpleExecContext : public ExecContext { return thread->readStCondFailures(); } - /** - * Executes a syscall specified by the callnum. - */ - void syscall() override { thread->syscall(); } - /** Returns a pointer to the ThreadContext. */ ThreadContext *tcBase() const override { return thread->getTC(); } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 5fe52cbd9..255140f67 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -585,8 +585,6 @@ class SimpleThread : public ThreadState, public ThreadContext return ThreadState::readFuncExeInst(); } - void syscall() override { process->syscall(this); } - RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; } void setIntRegFlat(RegIndex idx, RegVal val) override diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index 8cc7cec46..a6f7869b6 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -292,8 +292,6 @@ class ThreadContext : public PCEventScope // Same with st cond failures. virtual Counter readFuncExeInst() const = 0; - virtual void syscall() = 0; - // This function exits the thread context in the CPU and returns // 1 if the CPU has no more active threads (meaning it's OK to exit); // Used in syscall-emulation mode when a thread calls the exit syscall. diff --git a/src/sim/faults.cc b/src/sim/faults.cc index d4d3c112a..501b5d1e4 100644 --- a/src/sim/faults.cc +++ b/src/sim/faults.cc @@ -67,7 +67,7 @@ UnimpFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) void SESyscallFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) { - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); // Move the PC forward since that doesn't happen automatically. TheISA::PCState pc = tc->pcState(); inst->advancePC(pc); diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc index 7335fda4e..90db4bbc5 100644 --- a/src/sim/pseudo_inst.cc +++ b/src/sim/pseudo_inst.cc @@ -479,7 +479,7 @@ void m5Syscall(ThreadContext *tc) { DPRINTF(PseudoInst, "PseudoInst::m5Syscall()\n"); - tc->syscall(); + tc->getSystemPtr()->workload->syscall(tc); } void diff --git a/src/sim/se_workload.cc b/src/sim/se_workload.cc index f2a01d53a..dccd7ca5c 100644 --- a/src/sim/se_workload.cc +++ b/src/sim/se_workload.cc @@ -27,10 +27,17 @@ #include "sim/se_workload.hh" +#include "cpu/thread_context.hh" #include "params/SEWorkload.hh" +#include "sim/process.hh" SEWorkload::SEWorkload(const Params &p) : Workload(&p), _params(p) +{} + +void +SEWorkload::syscall(ThreadContext *tc) { + tc->getProcessPtr()->syscall(tc); } SEWorkload * diff --git a/src/sim/se_workload.hh b/src/sim/se_workload.hh index b72e8240d..8deb03b31 100644 --- a/src/sim/se_workload.hh +++ b/src/sim/se_workload.hh @@ -76,6 +76,8 @@ class SEWorkload : public Workload // within it. panic("No workload symbol table for syscall emulation mode."); } + + void syscall(ThreadContext *tc) override; }; #endif // __SIM_SE_WORKLOAD_HH__ diff --git a/src/sim/workload.hh b/src/sim/workload.hh index 435a24be2..7c1b66d39 100644 --- a/src/sim/workload.hh +++ b/src/sim/workload.hh @@ -69,6 +69,12 @@ class Workload : public SimObject virtual const Loader::SymbolTable &symtab(ThreadContext *tc) = 0; virtual bool insertSymbol(const Loader::Symbol &symbol) = 0; + virtual void + syscall(ThreadContext *tc) + { + panic("syscall() not implemented."); + } + /** @{ */ /** * Add a function-based event to the given function, to be looked -- 2.30.2