arch,cpu,sim: Route system calls through the workload.
authorGabe Black <gabeblack@google.com>
Sun, 23 Aug 2020 08:33:22 +0000 (01:33 -0700)
committerGabe Black <gabeblack@google.com>
Sun, 20 Sep 2020 07:26:42 +0000 (07:26 +0000)
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 <matthew.poremba@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
21 files changed:
src/arch/arm/faults.cc
src/arch/riscv/faults.cc
src/arch/sparc/linux/process.cc
src/cpu/checker/cpu.hh
src/cpu/checker/thread_context.hh
src/cpu/exec_context.hh
src/cpu/minor/exec_context.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/dyn_inst_impl.hh
src/cpu/o3/thread_context.hh
src/cpu/o3/thread_state.hh
src/cpu/simple/exec_context.hh
src/cpu/simple_thread.hh
src/cpu/thread_context.hh
src/sim/faults.cc
src/sim/pseudo_inst.cc
src/sim/se_workload.cc
src/sim/se_workload.hh
src/sim/workload.hh

index 56e1814c6c72186315323e9cadf406f689fee4d9..c590d78a51c88c4b215ed307dc216e80e4a61a58 100644 (file)
@@ -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();
index 7a1c7bd8c426025df5dc2784901e75e5f4ca9202..ac4c5823ed9d39848d04fc08210302aa193ef0c3 100644 (file)
@@ -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
index 79bbaeed2acdff5af9187bd5130d1387739a4861..ce051ba950605f04aa08afec6b250076a75c677a 100644 (file)
@@ -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);
index f2395d7b75a2f88937d883ebc4a50b686102659c..f5d7834921e894ce9fcc45e2523d08d61eeab0e7 100644 (file)
@@ -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()
index b5a974bcef6e0f45d112d1cbd8542566141b41c5..d07de62514e2e7b4615aac10e35b1f514bc43fe7 100644 (file)
@@ -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
index cfef3c3c98a7d76708b409ee53a6f80a7ecb4694..b1cdbd89c6d4aa640b8d9ae8bd1e5b082e551de1 100644 (file)
@@ -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;
 
index 81675e604c003936ce7b715842d0d806e18f529a..58301a07016e028f5cd64aab90e04e578c2e1e73 100644 (file)
@@ -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 */
index 01938f14119019d1cbbed6e6d1995c3d6ed2020d..11fac25a0f6e00ae9e6a7f661dac26d2708d93fc 100644 (file)
@@ -912,26 +912,6 @@ FullO3CPU<Impl>::trap(const Fault &fault, ThreadID tid,
     fault->invoke(this->threadContexts[tid], inst);
 }
 
-template <class Impl>
-void
-FullO3CPU<Impl>::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 <class Impl>
 void
 FullO3CPU<Impl>::serializeThread(CheckpointOut &cp, ThreadID tid) const
index 04472752ce2428432bfdabe5af26d6181ddd7d3a..200d34398ef001df9e733b9f64c9ff1eec5aa2cc 100644 (file)
@@ -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;
index 5f2a5886bb0d885a3e168e8f0280bad4e7645dd1..8172b9aa07fbafa7dbb5e30a7f9df6c52e3f8d3e 100644 (file)
@@ -248,9 +248,6 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     /** 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
index 8a6a434a055571ea426bcb30eaa05b6fe8ca1280..6c6625c43cfd8ebc1d28dda03a42f7be5796ac45 100644 (file)
@@ -187,19 +187,4 @@ BaseO3DynInst<Impl>::trap(const Fault &fault)
     this->cpu->trap(fault, this->threadNumber, this->staticInst);
 }
 
-template <class Impl>
-void
-BaseO3DynInst<Impl>::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__
index b3eba134deb2ee6b7a44a1371e4f95d1bb04774f..8d6edbf8d21e7b786814e79a5583471c99c2b455 100644 (file)
@@ -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; }
 
index 32268325ac685b6d12222130db0cbcb9c92951a1..285adeab1aca44aa783c495a4a7d09fed16af08c 100644 (file)
@@ -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__
index 2b2afd282f6090fb8199a9a0333b29bc4fd61aba..fbd2d96e1e36a57215d6bad8c66262301f753d71 100644 (file)
@@ -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(); }
 
index 5fe52cbd9f3a719ea475b5a5d265e4828e9a9b91..255140f674df947772feccc3b8b5beef3261985f 100644 (file)
@@ -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
index 8cc7cec46cdfc796dbf8e7f520660bcf36db22db..a6f7869b6334dd84cbe47ca21df8aab5681f0442 100644 (file)
@@ -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.
index d4d3c112a20376b1d40a264ce18df4e973a31bc8..501b5d1e451600858ccf96ebee9b2d65cd63712e 100644 (file)
@@ -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);
index 7335fda4e7e22bf471e3fb87c0fbbdc197bcb3bc..90db4bbc5d75df1f087b069a8afc9e6db1f90d2f 100644 (file)
@@ -479,7 +479,7 @@ void
 m5Syscall(ThreadContext *tc)
 {
     DPRINTF(PseudoInst, "PseudoInst::m5Syscall()\n");
-    tc->syscall();
+    tc->getSystemPtr()->workload->syscall(tc);
 }
 
 void
index f2a01d53a1b5f683ddb0aa2bf486208bbe265131..dccd7ca5c53b97840c20c5adf29a902a52cf434b 100644 (file)
 
 #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 *
index b72e8240db27c78c74db28492a2ae5cf8d6ae8f0..8deb03b31deac3c0c0383e8ef2965ae47ec97661 100644 (file)
@@ -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__
index 435a24be2ba521b57b6225e91832187e9aeb310d..7c1b66d39c9290683e8bf67e06e5812a6dd6c77f 100644 (file)
@@ -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