arch,sim-se: Handle syscall retry/suppression in the syscall desc.
Rather than make each ISA include boilerplate to ignore a SyscallReturn's value when it's marked as suppressed or needing a retry, put that code into the SyscallDesc::doSyscall method instead. That has two benefits. First, it removes a decent amount of code duplication which is nice from a maintenance perspective. Second, it puts the SyscallDesc in charge of figuring out what to do once a system call implementation finishes. That will let it schedule a retry of the system call for instance, without worrying about what the ISA is doing with the SyscallReturn behind its back. Jira Issue: https://gem5.atlassian.net/browse/GEM5-1123 Change-Id: I3732a98c8e0d0b2b94d61313960aa0782c0b971f Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/54023 Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
@@ -82,9 +82,6 @@ struct Result<ABI, SyscallReturn,
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
RegVal val;
|
||||
if (ret.successful()) {
|
||||
tc->setCCReg(ArmISA::CCREG_C, 0);
|
||||
|
||||
@@ -74,9 +74,6 @@ struct Result<ABI, SyscallReturn,
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
tc->setIntReg(ArmISA::ReturnValueReg, ret.encodedValue());
|
||||
if (ret.count() > 1)
|
||||
tc->setIntReg(ArmISA::SyscallPseudoReturnReg, ret.value2());
|
||||
|
||||
@@ -77,9 +77,6 @@ struct Result<MipsISA::SEWorkload::SyscallABI, SyscallReturn>
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
if (ret.successful()) {
|
||||
// no error
|
||||
tc->setIntReg(MipsISA::SyscallSuccessReg, 0);
|
||||
|
||||
@@ -77,9 +77,6 @@ struct Result<PowerISA::SEWorkload::SyscallABI, SyscallReturn>
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
PowerISA::Cr cr = tc->readIntReg(PowerISA::INTREG_CR);
|
||||
if (ret.successful()) {
|
||||
cr.cr0.so = 0;
|
||||
|
||||
@@ -75,9 +75,6 @@ struct Result<RiscvISA::SEWorkload::SyscallABI, SyscallReturn>
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
if (ret.successful()) {
|
||||
// no error
|
||||
tc->setIntReg(RiscvISA::ReturnValueReg, ret.returnValue());
|
||||
|
||||
@@ -89,9 +89,6 @@ struct Result<ABI, SyscallReturn,
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
// check for error condition. SPARC syscall convention is to
|
||||
// indicate success/failure in reg the carry bit of the ccr
|
||||
// and put the return value itself in the standard return value reg.
|
||||
|
||||
@@ -86,9 +86,6 @@ struct Result<ABI, SyscallReturn,
|
||||
static void
|
||||
store(ThreadContext *tc, const SyscallReturn &ret)
|
||||
{
|
||||
if (ret.suppressed() || ret.needsRetry())
|
||||
return;
|
||||
|
||||
tc->setIntReg(X86ISA::INTREG_RAX, ret.encodedValue());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,12 +44,14 @@ SyscallDesc::doSyscall(ThreadContext *tc)
|
||||
|
||||
SyscallReturn retval = executor(this, tc);
|
||||
|
||||
if (retval.needsRetry())
|
||||
if (retval.needsRetry()) {
|
||||
DPRINTF_SYSCALL(Base, "Needs retry.\n", name());
|
||||
else if (retval.suppressed())
|
||||
} else if (retval.suppressed()) {
|
||||
DPRINTF_SYSCALL(Base, "No return value.\n", name());
|
||||
else
|
||||
} else {
|
||||
returnInto(tc, retval);
|
||||
DPRINTF_SYSCALL(Base, "Returned %d.\n", retval.encodedValue());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
@@ -141,7 +141,7 @@ class SyscallDescABI : public SyscallDesc
|
||||
|
||||
// Use invokeSimcall to gather the other arguments based on the
|
||||
// given ABI and pass them to the syscall implementation.
|
||||
return invokeSimcall<ABI, SyscallReturn, Args...>(tc,
|
||||
return invokeSimcall<ABI, false, SyscallReturn, Args...>(tc,
|
||||
std::function<SyscallReturn(ThreadContext *, Args...)>(
|
||||
partial));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user