summaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-01-18 21:54:54 +0100
committerEric W. Biederman <ebiederm@xmission.com>2018-01-23 02:07:09 +0100
commitf8ec66014ffd95a783b1f9f3b62d7cadb96b78d5 (patch)
tree6e57bcf6bcd9e70ccc1b1cd89345299dc9105a33 /kernel/signal.c
parentsignal: Replace memset(info,...) with clear_siginfo for clarity (diff)
downloadlinux-f8ec66014ffd95a783b1f9f3b62d7cadb96b78d5.tar.xz
linux-f8ec66014ffd95a783b1f9f3b62d7cadb96b78d5.zip
signal: Add send_sig_fault and force_sig_fault
The vast majority of signals sent from architecture specific code are simple faults. Encapsulate this reality with two helper functions so that the nit-picky implementation of preparing a siginfo does not need to be repeated many times on each architecture. As only some architectures support the trapno field, make the trapno arguement only present on those architectures. Similary as ia64 has three fields: imm, flags, and isr that are specific to it. Have those arguments always present on ia64 and no where else. This ensures the architecture specific code always remembers which fields it needs to pass into the siginfo structure. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index f14492ff976f..15ec7b3cbe69 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1491,6 +1491,53 @@ force_sigsegv(int sig, struct task_struct *p)
return 0;
}
+int force_sig_fault(int sig, int code, void __user *addr
+ ___ARCH_SI_TRAPNO(int trapno)
+ ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
+ , struct task_struct *t)
+{
+ struct siginfo info;
+
+ clear_siginfo(&info);
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = code;
+ info.si_addr = addr;
+#ifdef __ARCH_SI_TRAPNO
+ info.si_trapno = trapno;
+#endif
+#ifdef __ia64__
+ info.si_imm = imm;
+ info.si_flags = flags;
+ info.si_isr = isr;
+#endif
+ return force_sig_info(info.si_signo, &info, t);
+}
+
+int send_sig_fault(int sig, int code, void __user *addr
+ ___ARCH_SI_TRAPNO(int trapno)
+ ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
+ , struct task_struct *t)
+{
+ struct siginfo info;
+
+ clear_siginfo(&info);
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = code;
+ info.si_addr = addr;
+#ifdef __ARCH_SI_TRAPNO
+ info.si_trapno = trapno;
+#endif
+#ifdef __ia64__
+ info.si_imm = imm;
+ info.si_flags = flags;
+ info.si_isr = isr;
+#endif
+ return send_sig_info(info.si_signo, &info, t);
+}
+
+
int kill_pgrp(struct pid *pid, int sig, int priv)
{
int ret;