diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/faults.cc | 5 | ||||
-rw-r--r-- | src/sim/faults.hh | 16 | ||||
-rw-r--r-- | src/sim/process.cc | 4 | ||||
-rw-r--r-- | src/sim/process.hh | 2 | ||||
-rw-r--r-- | src/sim/syscall_desc.cc | 12 | ||||
-rw-r--r-- | src/sim/syscall_desc.hh | 5 |
6 files changed, 37 insertions, 7 deletions
diff --git a/src/sim/faults.cc b/src/sim/faults.cc index 93e766526..b0fa6fedb 100644 --- a/src/sim/faults.cc +++ b/src/sim/faults.cc @@ -59,6 +59,11 @@ void ReExec::invoke(ThreadContext *tc, const StaticInstPtr &inst) tc->pcState(tc->pcState()); } +void SyscallRetryFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) +{ + tc->pcState(tc->pcState()); +} + void GenericPageTableFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) { bool handled = false; diff --git a/src/sim/faults.hh b/src/sim/faults.hh index da0ea22fa..be7aab582 100644 --- a/src/sim/faults.hh +++ b/src/sim/faults.hh @@ -72,6 +72,22 @@ class ReExec : public FaultBase StaticInst::nullStaticInstPtr); }; +/* + * This class is needed to allow system call retries to occur for blocking + * system calls in SE mode. A retry fault will be generated by the system call + * emulation code if blocking conditions arise; the fault is passed up the + * function call chain into the CPU model where it is handled by retrying the + * syscall instruction on a later tick. + */ +class SyscallRetryFault : public FaultBase +{ + public: + virtual FaultName name() const { return "System call retry fault"; } + SyscallRetryFault() {} + void invoke(ThreadContext *tc, const StaticInstPtr &inst = + StaticInst::nullStaticInstPtr); +}; + class GenericPageTableFault : public FaultBase { private: diff --git a/src/sim/process.cc b/src/sim/process.cc index 4c44f4086..5acfa88b3 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -269,7 +269,7 @@ Process::map(Addr vaddr, Addr paddr, int size, bool cacheable) } void -Process::syscall(int64_t callnum, ThreadContext *tc) +Process::syscall(int64_t callnum, ThreadContext *tc, Fault *fault) { num_syscalls++; @@ -277,7 +277,7 @@ Process::syscall(int64_t callnum, ThreadContext *tc) if (desc == NULL) fatal("Syscall %d out of range", callnum); - desc->doSyscall(callnum, this, tc); + desc->doSyscall(callnum, this, tc, fault); } IntReg diff --git a/src/sim/process.hh b/src/sim/process.hh index 2191c3cd0..101e4a31c 100644 --- a/src/sim/process.hh +++ b/src/sim/process.hh @@ -80,7 +80,7 @@ class Process : public SimObject void initState() override; DrainState drain() override; - void syscall(int64_t callnum, ThreadContext *tc); + void syscall(int64_t callnum, ThreadContext *tc, Fault *fault); virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i) = 0; virtual TheISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); virtual void setSyscallArg(ThreadContext *tc, int i, diff --git a/src/sim/syscall_desc.cc b/src/sim/syscall_desc.cc index bb0e80f5f..13b519081 100644 --- a/src/sim/syscall_desc.cc +++ b/src/sim/syscall_desc.cc @@ -33,16 +33,21 @@ #include "sim/syscall_desc.hh" +#include <memory> + #include "base/trace.hh" +#include "base/types.hh" #include "config/the_isa.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" +#include "sim/faults.hh" #include "sim/process.hh" #include "sim/syscall_debug_macros.hh" #include "sim/syscall_return.hh" void -SyscallDesc::doSyscall(int callnum, Process *process, ThreadContext *tc) +SyscallDesc::doSyscall(int callnum, Process *process, ThreadContext *tc, + Fault *fault) { TheISA::IntReg arg[6] M5_VAR_USED; @@ -71,9 +76,10 @@ SyscallDesc::doSyscall(int callnum, Process *process, ThreadContext *tc) * blocking behavior, warn that the system call will retry; * alternatively, print the return value. */ - if (retval.needsRetry()) + if (retval.needsRetry()) { + *fault = std::make_shared<SyscallRetryFault>(); DPRINTF_SYSCALL(Base, "%s needs retry\n", _name); - else + } else DPRINTF_SYSCALL(Base, "%s returns %d\n", _name, retval.encodedValue()); if (!(_flags & SyscallDesc::SuppressReturnValue) && !retval.needsRetry()) diff --git a/src/sim/syscall_desc.hh b/src/sim/syscall_desc.hh index 37aaad14d..b4d24e672 100644 --- a/src/sim/syscall_desc.hh +++ b/src/sim/syscall_desc.hh @@ -48,6 +48,8 @@ #include <string> +#include "base/types.hh" + class Process; class SyscallReturn; class ThreadContext; @@ -91,7 +93,8 @@ class SyscallDesc { * @param proc Handle for the owning Process to pass information * @param tc Handle for owning ThreadContext to pass information */ - void doSyscall(int callnum, Process *proc, ThreadContext *tc); + void doSyscall(int callnum, Process *proc, ThreadContext *tc, + Fault *fault); /** * Return false if WarnOnce is set and a warning has already been issued. |