syscall-emul: Add the tgkill system call
authorBrandon Potter <Brandon.Potter@amd.com>
Wed, 1 Mar 2017 20:34:11 +0000 (14:34 -0600)
committerBrandon Potter <Brandon.Potter@amd.com>
Thu, 9 Mar 2017 22:42:45 +0000 (22:42 +0000)
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>
src/arch/x86/linux/process.cc
src/sim/syscall_emul.hh

index aad5151f6ebc7b946a224e9112b4bdffb42f84e7..be572295b37d4dc135bdc423308f6bc0a20ee65f 100644 (file)
@@ -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<X86Linux64>),
     /* 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<X86Linux32>),
     /* 271 */ SyscallDesc("utimes", unimplementedFunc),
     /* 272 */ SyscallDesc("fadvise64_64", unimplementedFunc),
     /* 273 */ SyscallDesc("vserver", unimplementedFunc),
index d75841cc6d5b9b322d901c5cd3f2137e730566b6..2380e4779841f4ca63ab2dcdf0987e465e0684c3 100644 (file)
@@ -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__