From 6f7bf1b11fd9a2d7c2007fd0aca3ffa4885a215e Mon Sep 17 00:00:00 2001 From: Brandon Potter Date: Wed, 1 Mar 2017 14:34:11 -0600 Subject: [PATCH] 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/arch/x86/linux/process.cc | 4 +-- src/sim/syscall_emul.hh | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index aad5151f6..be572295b 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -454,7 +454,7 @@ static SyscallDesc syscallDescs64[] = { /* 231 */ SyscallDesc("exit_group", exitGroupFunc), /* 232 */ SyscallDesc("epoll_wait", unimplementedFunc), /* 233 */ SyscallDesc("epoll_ctl", unimplementedFunc), - /* 234 */ SyscallDesc("tgkill", unimplementedFunc), + /* 234 */ SyscallDesc("tgkill", tgkillFunc), /* 235 */ SyscallDesc("utimes", unimplementedFunc), /* 236 */ SyscallDesc("vserver", unimplementedFunc), /* 237 */ SyscallDesc("mbind", unimplementedFunc), @@ -819,7 +819,7 @@ static SyscallDesc syscallDescs32[] = { /* 267 */ SyscallDesc("clock_nanosleep", unimplementedFunc), /* 268 */ SyscallDesc("statfs64", unimplementedFunc), /* 269 */ SyscallDesc("fstatfs64", unimplementedFunc), - /* 270 */ SyscallDesc("tgkill", unimplementedFunc), + /* 270 */ SyscallDesc("tgkill", tgkillFunc), /* 271 */ SyscallDesc("utimes", unimplementedFunc), /* 272 */ SyscallDesc("fadvise64_64", unimplementedFunc), /* 273 */ SyscallDesc("vserver", unimplementedFunc), 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__