summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
authorBrandon Potter <Brandon.Potter@amd.com>2017-03-01 14:34:11 -0600
committerBrandon Potter <Brandon.Potter@amd.com>2017-03-09 22:42:45 +0000
commit6f7bf1b11fd9a2d7c2007fd0aca3ffa4885a215e (patch)
treec2db74813e2efa754d5d56067505aee8bd26d6e3 /src/sim
parent8b85f950e5a4f0f7ebf66f142356d8dcea7c9bcc (diff)
downloadgem5-6f7bf1b11fd9a2d7c2007fd0aca3ffa4885a215e.tar.xz
syscall-emul: Add the tgkill system call
This changeset adds support to kill a thread group by calling the tgkill system call. The functionality is needed in some pthread applications. Change-Id: I0413a3331be69b74dfab30de95384113ec4efb63 Reviewed-on: https://gem5-review.googlesource.com/2268 Maintainer: Jason Lowe-Power <jason@lowepower.com> Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com> Reviewed-by: Michael LeBeane <Michael.Lebeane@amd.com>
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/syscall_emul.hh49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index d75841cc6..2380e4779 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -1973,5 +1973,54 @@ timeFunc(SyscallDesc *desc, int callnum, Process *process, ThreadContext *tc)
return sec;
}
+template <class OS>
+SyscallReturn
+tgkillFunc(SyscallDesc *desc, int num, Process *process, ThreadContext *tc)
+{
+ int index = 0;
+ int tgid = process->getSyscallArg(tc, index);
+ int tid = process->getSyscallArg(tc, index);
+ int sig = process->getSyscallArg(tc, index);
+
+ /**
+ * This system call is intended to allow killing a specific thread
+ * within an arbitrary thread group if sanctioned with permission checks.
+ * It's usually true that threads share the termination signal as pointed
+ * out by the pthread_kill man page and this seems to be the intended
+ * usage. Due to this being an emulated environment, assume the following:
+ * Threads are allowed to call tgkill because the EUID for all threads
+ * should be the same. There is no signal handling mechanism for kernel
+ * registration of signal handlers since signals are poorly supported in
+ * emulation mode. Since signal handlers cannot be registered, all
+ * threads within in a thread group must share the termination signal.
+ * We never exhaust PIDs so there's no chance of finding the wrong one
+ * due to PID rollover.
+ */
+
+ System *sys = tc->getSystemPtr();
+ Process *tgt_proc = nullptr;
+ for (int i = 0; i < sys->numContexts(); i++) {
+ Process *temp = sys->threadContexts[i]->getProcessPtr();
+ if (temp->pid() == tid) {
+ tgt_proc = temp;
+ break;
+ }
+ }
+
+ if (sig != 0 || sig != OS::TGT_SIGABRT)
+ return -EINVAL;
+
+ if (tgt_proc == nullptr)
+ return -ESRCH;
+
+ if (tgid != -1 && tgt_proc->tgid() != tgid)
+ return -ESRCH;
+
+ if (sig == OS::TGT_SIGABRT)
+ exitGroupFunc(desc, 252, process, tc);
+
+ return 0;
+}
+
#endif // __SIM_SYSCALL_EMUL_HH__