Module Name:    src
Committed By:   thorpej
Date:           Sun Sep 19 17:33:39 UTC 2021

Modified Files:
        src/sys/compat/linux/common: linux_sigevent.h linux_signal.c

Log Message:
- LINUX_SIGEV_PAD is incorrect for 64-bit systems, because sigval_t
  contains a pointer.  Correct this.
- Add routines to convert from Linux to native sigevent_t.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/compat/linux/common/linux_sigevent.h
cvs rdiff -u -r1.84 -r1.85 src/sys/compat/linux/common/linux_signal.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/linux/common/linux_sigevent.h
diff -u src/sys/compat/linux/common/linux_sigevent.h:1.2 src/sys/compat/linux/common/linux_sigevent.h:1.3
--- src/sys/compat/linux/common/linux_sigevent.h:1.2	Mon Apr 28 20:23:44 2008
+++ src/sys/compat/linux/common/linux_sigevent.h	Sun Sep 19 17:33:39 2021
@@ -37,13 +37,16 @@
 
 #define LINUX_SIGEV_MAX  64
 #ifndef LINUX_SIGEV_PAD
-#define LINUX_SIGEV_PAD  ((LINUX_SIGEV_MAX/sizeof(int)) - 3)
+#define LINUX_SIGEV_PAD  ((LINUX_SIGEV_MAX -				\
+			   (sizeof(sigval_t) + (sizeof(int) * 2))) /	\
+			  sizeof(int))
 #endif
 
 typedef struct linux_sigevent {
-	sigval_t sigev_value;
+	sigval_t sigev_value;		/* sizeof(pointer) */
 	int sigev_signo;
 	int sigev_notify;
+	/* guaranteed to have natural pointer alignment */
 	union {
 		int pad[LINUX_SIGEV_PAD];
 		int tid;
@@ -54,4 +57,8 @@ typedef struct linux_sigevent {
 	} _sigev_un;
 } linux_sigevent_t;
 
+int	linux_to_native_sigevent(struct sigevent *,
+	    const struct linux_sigevent *);
+int	linux_sigevent_copyin(const void *, void *, size_t);
+
 #endif /* _LINUX_SIGEVENT_H */

Index: src/sys/compat/linux/common/linux_signal.c
diff -u src/sys/compat/linux/common/linux_signal.c:1.84 src/sys/compat/linux/common/linux_signal.c:1.85
--- src/sys/compat/linux/common/linux_signal.c:1.84	Tue Sep  7 11:43:04 2021
+++ src/sys/compat/linux/common/linux_signal.c	Sun Sep 19 17:33:39 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_signal.c,v 1.84 2021/09/07 11:43:04 riastradh Exp $	*/
+/*	$NetBSD: linux_signal.c,v 1.85 2021/09/19 17:33:39 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.84 2021/09/07 11:43:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.85 2021/09/19 17:33:39 thorpej Exp $");
 
 #define COMPAT_LINUX 1
 
@@ -852,3 +852,50 @@ native_to_linux_si_status(int code, int 
 
 	return sts;
 }
+
+int
+linux_to_native_sigevent(struct sigevent *nsep,
+    const struct linux_sigevent *lsep)
+{
+	memset(nsep, 0, sizeof(*nsep));
+
+	switch (lsep->sigev_notify) {
+	case LINUX_SIGEV_SIGNAL:
+		nsep->sigev_notify = SIGEV_SIGNAL;
+		break;
+
+	case LINUX_SIGEV_NONE:
+		nsep->sigev_notify = SIGEV_NONE;
+		break;
+
+	case LINUX_SIGEV_THREAD:
+	case LINUX_SIGEV_THREAD_ID:
+	default:
+		return ENOTSUP;
+	}
+
+	nsep->sigev_value = lsep->sigev_value;
+	if (lsep->sigev_signo < 0 || lsep->sigev_signo >= LINUX__NSIG) {
+		return EINVAL;
+	}
+	nsep->sigev_signo = linux_to_native_signo[lsep->sigev_signo];
+
+	return 0;
+}
+
+int
+linux_sigevent_copyin(const void *src, void *dst, size_t size)
+{
+	struct linux_sigevent lse;
+	struct sigevent *sep = dst;
+	int error;
+
+	KASSERT(size == sizeof(*sep));
+
+	error = copyin(src, &lse, sizeof(lse));
+	if (error) {
+		return error;
+	}
+
+	return linux_to_native_sigevent(sep, &lse);
+}

Reply via email to