summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/faults.cc5
-rw-r--r--src/sim/faults.hh16
-rw-r--r--src/sim/process.cc4
-rw-r--r--src/sim/process.hh2
-rw-r--r--src/sim/syscall_desc.cc12
-rw-r--r--src/sim/syscall_desc.hh5
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.