Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux/common - LINUX_SIGEV_PAD is incorrect for 6...



details:   https://anonhg.NetBSD.org/src/rev/f792433dbe6c
branches:  trunk
changeset: 986320:f792433dbe6c
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Sep 19 17:33:39 2021 +0000

description:
- 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.

diffstat:

 sys/compat/linux/common/linux_sigevent.h |  11 +++++-
 sys/compat/linux/common/linux_signal.c   |  51 ++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 4 deletions(-)

diffs (100 lines):

diff -r 57b9a8e616aa -r f792433dbe6c sys/compat/linux/common/linux_sigevent.h
--- a/sys/compat/linux/common/linux_sigevent.h  Sun Sep 19 17:10:41 2021 +0000
+++ b/sys/compat/linux/common/linux_sigevent.h  Sun Sep 19 17:33:39 2021 +0000
@@ -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 @@
        } _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 */
diff -r 57b9a8e616aa -r f792433dbe6c sys/compat/linux/common/linux_signal.c
--- a/sys/compat/linux/common/linux_signal.c    Sun Sep 19 17:10:41 2021 +0000
+++ b/sys/compat/linux/common/linux_signal.c    Sun Sep 19 17:33:39 2021 +0000
@@ -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 @@
 
        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);
+}



Home | Main Index | Thread Index | Old Index