diff options
author | Gabe Black <gabeblack@google.com> | 2019-11-25 01:07:41 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2019-12-10 23:58:14 +0000 |
commit | cb3457ccd17a89a4df3e70d35e0254c77a0b5782 (patch) | |
tree | 6693c6acb869246269906c5227f1331a78a6262d /src/cpu | |
parent | d142a1547cfc7e06964e2cb34905f3e4304c93fd (diff) | |
download | gem5-cb3457ccd17a89a4df3e70d35e0254c77a0b5782.tar.xz |
arch,cpu,sim: Push syscall number determination up to processes.
The logic that determines which syscall to call was built into the
implementation of faults/exceptions or even into the instruction
decoder, but that logic can depend on what OS is being used, and
sometimes even what version, for example 32bit vs. 64bit.
This change pushes that logic up into the Process objects since those
already handle a lot of the aspects of emulating the guest OS. Instead,
the ISA or fault implementations just notify the rest of the system
that a nebulous syscall has happened, and that gets propogated upward
until the process does something with it. That's very analogous to how
a system call would work on a real machine.
When a system call happens, the low level component which detects that
should call tc->syscall(&fault), where tc is the relevant thread (or
execution) context, and fault is a Fault which can ultimately be set
by the system call implementation.
The TC implementor (probably a CPU) will then have a chance to do
whatever it needs to to handle a system call. Currently only O3 does
anything special here. That implementor will end up calling the
Process's syscall() method.
Once in Process::syscall, the process object will use it's contextual
knowledge to determine what system call is being requested. It then
calls Process::doSyscall with the right syscall number, where doSyscall
centralizes the common mechanism for actually retrieving and calling
into the system call implementation.
Jira Issue: https://gem5.atlassian.net/browse/GEM5-187
Change-Id: I937ec1ef0576142c2a182ff33ca508d77ad0e7a1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23176
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/checker/cpu.hh | 2 | ||||
-rw-r--r-- | src/cpu/checker/thread_context.hh | 4 | ||||
-rw-r--r-- | src/cpu/exec_context.hh | 4 | ||||
-rw-r--r-- | src/cpu/minor/exec_context.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 4 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/thread_context.hh | 4 | ||||
-rw-r--r-- | src/cpu/o3/thread_state.hh | 5 | ||||
-rw-r--r-- | src/cpu/simple/exec_context.hh | 4 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 5 | ||||
-rw-r--r-- | src/cpu/thread_context.hh | 2 |
13 files changed, 22 insertions, 24 deletions
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 8db6aa376..e50afebf5 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -581,7 +581,7 @@ 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(int64_t callnum, Fault *fault) override { } + void syscall(Fault *fault) override { } void handleError() diff --git a/src/cpu/checker/thread_context.hh b/src/cpu/checker/thread_context.hh index dbdfa80cd..0fb75562a 100644 --- a/src/cpu/checker/thread_context.hh +++ b/src/cpu/checker/thread_context.hh @@ -184,9 +184,9 @@ class CheckerThreadContext : public ThreadContext /** Executes a syscall in SE mode. */ void - syscall(int64_t callnum, Fault *fault) override + syscall(Fault *fault) override { - return actualTC->syscall(callnum, fault); + return actualTC->syscall(fault); } Status status() const override { return actualTC->status(); } diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh index a2b392492..80f3edaee 100644 --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -304,9 +304,9 @@ class ExecContext { */ /** - * Executes a syscall specified by the callnum. + * Executes a syscall. */ - virtual void syscall(int64_t callnum, Fault *fault) = 0; + virtual void syscall(Fault *fault) = 0; /** @} */ diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh index 66e313eb3..184dd2910 100644 --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -387,9 +387,9 @@ class ExecContext : public ::ExecContext } void - syscall(int64_t callnum, Fault *fault) override + syscall(Fault *fault) override { - thread.syscall(callnum, fault); + thread.syscall(fault); } ThreadContext *tcBase() override { return thread.getTC(); } diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index c843db3a0..996f6360b 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -918,7 +918,7 @@ FullO3CPU<Impl>::trap(const Fault &fault, ThreadID tid, template <class Impl> void -FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault) +FullO3CPU<Impl>::syscall(ThreadID tid, Fault *fault) { DPRINTF(O3CPU, "[tid:%i] Executing syscall().\n\n", tid); @@ -929,7 +929,7 @@ FullO3CPU<Impl>::syscall(int64_t callnum, ThreadID tid, Fault *fault) ++(this->thread[tid]->funcExeInst); // Execute the actual syscall. - this->thread[tid]->syscall(callnum, fault); + this->thread[tid]->syscall(fault); // Decrease funcExeInst by one as the normal commit will handle // incrementing it. diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index b06182d43..7c0ea5166 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -284,7 +284,7 @@ class FullO3CPU : public BaseO3CPU /** Executes a syscall. * @todo: Determine if this needs to be virtual. */ - void syscall(int64_t callnum, ThreadID tid, Fault *fault); + void syscall(ThreadID tid, Fault *fault); /** Starts draining the CPU's pipeline of all instructions in * order to stop all memory accesses. */ diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index 131ffd258..a136e9019 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -252,7 +252,7 @@ class BaseO3DynInst : public BaseDynInst<Impl> void trap(const Fault &fault); /** Emulates a syscall. */ - void syscall(int64_t callnum, Fault *fault) override; + void syscall(Fault *fault) override; public: diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 22d89ec0b..a9fc990ec 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -192,13 +192,13 @@ BaseO3DynInst<Impl>::trap(const Fault &fault) template <class Impl> void -BaseO3DynInst<Impl>::syscall(int64_t callnum, Fault *fault) +BaseO3DynInst<Impl>::syscall(Fault *fault) { // 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(callnum, this->threadNumber, fault); + this->cpu->syscall(this->threadNumber, fault); TheISA::PCState newPC = this->cpu->pcState(this->threadNumber); if (!(curPC == newPC)) { this->pcState(newPC); diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index c68f34c07..a01c05413 100644 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -448,9 +448,9 @@ class O3ThreadContext : public ThreadContext /** Executes a syscall in SE mode. */ void - syscall(int64_t callnum, Fault *fault) override + syscall(Fault *fault) override { - return cpu->syscall(callnum, thread->threadId(), fault); + return cpu->syscall(thread->threadId(), fault); } /** Reads the funcExeInst counter. */ diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index a0c3a8171..024ebd074 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -148,10 +148,9 @@ struct O3ThreadState : public ThreadState { ThreadContext *getTC() { return tc; } /** Handles the syscall. */ - void syscall(int64_t callnum, Fault *fault) + void syscall(Fault *fault) { - fatal_if(FullSystem, "System call emulation is unavailable!"); - process->syscall(callnum, tc, fault); + process->syscall(tc, fault); } void dumpFuncProfile() diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh index 4d26dfe2a..48a9f9423 100644 --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -497,9 +497,9 @@ class SimpleExecContext : public ExecContext { * Executes a syscall specified by the callnum. */ void - syscall(int64_t callnum, Fault *fault) override + syscall(Fault *fault) override { - thread->syscall(callnum, fault); + thread->syscall(fault); } /** Returns a pointer to the ThreadContext. */ diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 387e74546..b4afcbbc8 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -609,10 +609,9 @@ class SimpleThread : public ThreadState, public ThreadContext } void - syscall(int64_t callnum, Fault *fault) override + syscall(Fault *fault) override { - fatal_if(FullSystem, "System call emulation is unavailable!"); - process->syscall(callnum, this, fault); + process->syscall(this, fault); } RegVal readIntRegFlat(RegIndex idx) const override { return intRegs[idx]; } diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh index a77ac4848..c14161d6f 100644 --- a/src/cpu/thread_context.hh +++ b/src/cpu/thread_context.hh @@ -307,7 +307,7 @@ class ThreadContext : public PCEventScope // Same with st cond failures. virtual Counter readFuncExeInst() const = 0; - virtual void syscall(int64_t callnum, Fault *fault) = 0; + virtual void syscall(Fault *fault) = 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); |