From 6f7bf1b11fd9a2d7c2007fd0aca3ffa4885a215e Mon Sep 17 00:00:00 2001 From: Brandon Potter Date: Wed, 1 Mar 2017 14:34:11 -0600 Subject: 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 Reviewed-by: Tony Gutierrez Reviewed-by: Michael LeBeane --- src/sim/syscall_emul.hh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'src/sim/syscall_emul.hh') 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 +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__ -- cgit v1.2.3