tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Unused SI_LWP si_code definition ?
On Wed, Oct 15, 2008 at 05:42:30PM +0200, Nicolas Joly wrote:
>
> While looking into existing si_code values, i discovered SI_LWP
> definition (src/sys/sys/siginfo.h). According to the corresponding
> comment it should be set by _lwp_kill(2), but it SI_USER is set
> instead ... So this value is currently unused.
>
> For compat linux NPTL emulation, i do need this functionality, where 2
> syscalls tkill and tgkill set up si_code to SI_TKILL. This value is
> needed by a handler in libpthread to switch a bit, allowing threads to
> be properly cancelled.
Attached a preliminary patch (native to linux si_code conversion need
some more work), which fix some pthread cancellation problems/hangs
under amd64 NPTL compat linux emulation.
--
Nicolas Joly
Biological Software and Databanks.
Institut Pasteur, Paris.
Index: sys/compat/linux/arch/amd64/linux_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/amd64/linux_machdep.c,v
retrieving revision 1.32
diff -u -p -r1.32 linux_machdep.c
--- sys/compat/linux/arch/amd64/linux_machdep.c 18 Sep 2008 15:57:04 -0000
1.32
+++ sys/compat/linux/arch/amd64/linux_machdep.c 15 Oct 2008 21:59:17 -0000
@@ -230,7 +230,8 @@ linux_sendsig(const ksiginfo_t *ksi, con
*/
sigframe.info.lsi_signo = native_to_linux_signo[sig];
sigframe.info.lsi_errno = native_to_linux_errno[ksi->ksi_errno];
- sigframe.info.lsi_code = ksi->ksi_code;
+ sigframe.info.lsi_code =
+ (ksi->ksi_code == SI_LWP) ? LINUX_SI_TKILL : ksi->ksi_code;
/* XXX This is a rought conversion, taken from i386 code */
switch (sigframe.info.lsi_signo) {
Index: sys/compat/linux/common/linux_siginfo.h
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_siginfo.h,v
retrieving revision 1.11
diff -u -p -r1.11 linux_siginfo.h
--- sys/compat/linux/common/linux_siginfo.h 28 Apr 2008 20:23:44 -0000
1.11
+++ sys/compat/linux/common/linux_siginfo.h 15 Oct 2008 21:59:17 -0000
@@ -48,6 +48,16 @@
#include <compat/linux/arch/amd64/linux_siginfo.h>
#endif
+/* si_code values */
+#define LINUX_SI_USER 0
+#define LINUX_SI_QUEUE -1
+#define LINUX_SI_TIMER -2
+#define LINUX_SI_MESGQ -3
+#define LINUX_SI_ASYNCIO -4
+#define LINUX_SI_SIGIO -5
+#define LINUX_SI_TKILL -6
+#define LINUX_SI_DETHREAD -7
+
/* From linux/include/asm-generic/siginfo.h */
#define LINUX_CLD_EXITED 1
#define LINUX_CLD_KILLED 2
Index: sys/compat/linux/common/linux_signal.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_signal.c,v
retrieving revision 1.63
diff -u -p -r1.63 linux_signal.c
--- sys/compat/linux/common/linux_signal.c 30 Jul 2008 16:05:26 -0000
1.63
+++ sys/compat/linux/common/linux_signal.c 15 Oct 2008 21:59:17 -0000
@@ -604,6 +604,45 @@ linux_sys_sigaltstack(struct lwp *l, con
#endif /* LINUX_SS_ONSTACK */
#ifdef LINUX_NPTL
+static int
+linux_do_tkill(struct lwp *l, int tgid, int tid, int signum)
+{
+ struct proc *p;
+ int error;
+ ksiginfo_t ksi;
+ struct linux_emuldata *led;
+
+ if (signum < 0 || signum >= LINUX__NSIG)
+ return EINVAL;
+ signum = linux_to_native_signo[signum];
+
+ KSI_INIT(&ksi);
+ ksi.ksi_signo = signum;
+ ksi.ksi_code = SI_LWP;
+ ksi.ksi_pid = l->l_proc->p_pid;
+ ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
+
+ mutex_enter(proc_lock);
+ if ((p = p_find(tid, PFIND_LOCKED)) == NULL) {
+ mutex_exit(proc_lock);
+ return ESRCH;
+ }
+ led = p->p_emuldata;
+ if (tgid > 0 && led->s->group_pid != tgid) {
+ mutex_exit(proc_lock);
+ return ESRCH;
+ }
+ mutex_enter(p->p_lock);
+ error = kauth_authorize_process(l->l_cred,
+ KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(signum), NULL, NULL);
+ if (!error && signum)
+ kpsignal2(p, &ksi);
+ mutex_exit(p->p_lock);
+ mutex_exit(proc_lock);
+
+ return error;
+}
+
int
linux_sys_tkill(struct lwp *l, const struct linux_sys_tkill_args *uap,
register_t *retval)
{
@@ -611,13 +650,11 @@ linux_sys_tkill(struct lwp *l, const str
syscallarg(int) tid;
syscallarg(int) sig;
} */
- struct linux_sys_kill_args cup;
- /* We use the PID as the TID ... */
- SCARG(&cup, pid) = SCARG(uap, tid);
- SCARG(&cup, signum) = SCARG(uap, sig);
+ if (SCARG(uap, tid) <= 0)
+ return EINVAL;
- return linux_sys_kill(l, &cup, retval);
+ return linux_do_tkill(l, 0, SCARG(uap, tid), SCARG(uap, sig));
}
int
@@ -628,31 +665,10 @@ linux_sys_tgkill(struct lwp *l, const st
syscallarg(int) tid;
syscallarg(int) sig;
} */
- struct linux_sys_kill_args cup;
- struct linux_emuldata *led;
- struct proc *p;
- SCARG(&cup, pid) = SCARG(uap, tid);
- SCARG(&cup, signum) = SCARG(uap, sig);
-
- if (SCARG(uap, tgid) == -1)
- return linux_sys_kill(l, &cup, retval);
-
- /* We use the PID as the TID, but make sure the group ID is right */
- /* XXX racy */
- mutex_enter(proc_lock);
- if ((p = p_find(SCARG(uap, tid), PFIND_LOCKED)) == NULL ||
- p->p_emul != &emul_linux) {
- mutex_exit(proc_lock);
- return ESRCH;
- }
- led = p->p_emuldata;
- if (led->s->group_pid != SCARG(uap, tgid)) {
- mutex_exit(proc_lock);
- return ESRCH;
- }
- mutex_exit(proc_lock);
+ if (SCARG(uap, tid) <= 0 || SCARG(uap, tgid) <= 0)
+ return EINVAL;
- return linux_sys_kill(l, &cup, retval);
+ return linux_do_tkill(l, SCARG(uap, tgid), SCARG(uap, tid), SCARG(uap,
sig));
}
#endif /* LINUX_NPTL */
Home |
Main Index |
Thread Index |
Old Index