The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=fa8fdd80dff94dc848b449282080a5d85a3e6012

commit fa8fdd80dff94dc848b449282080a5d85a3e6012
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-03-13 23:05:21 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-03-24 02:24:14 +0000

    sysctl KERN_PROC_KQUEUE: implement compat32
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D49372
---
 sys/compat/freebsd32/freebsd32.h      | 18 +++++++++++++
 sys/compat/freebsd32/freebsd32_misc.c | 50 +++++++++++++++++++++++++++++++++++
 sys/compat/freebsd32/freebsd32_util.h |  5 ++++
 sys/kern/kern_event.c                 | 38 +++++++++++++++++---------
 4 files changed, 98 insertions(+), 13 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index 3dbf1b5a876d..2db154a8155c 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -446,6 +446,24 @@ struct kinfo_vm_layout32 {
        uint32_t        kvm_spare[12];
 };
 
+struct kinfo_knote32 {
+       int             knt_kq_fd;
+       struct kevent32 knt_event;
+       int             knt_status;
+       int             knt_extdata;
+       union {
+               struct {
+                       int             knt_vnode_type;
+                       uint32_t        knt_vnode_fsid[2];
+                       uint32_t        knt_vnode_fileid[2];
+                       char            knt_vnode_fullpath[PATH_MAX];
+               } knt_vnode;
+               struct {
+                       uint32_t        knt_pipe_ino[2];
+               } knt_pipe;
+       };
+};
+
 struct kld_file_stat_1_32 {
        int     version;        /* set to sizeof(struct kld_file_stat_1) */
        char    name[MAXPATHLEN];
diff --git a/sys/compat/freebsd32/freebsd32_misc.c 
b/sys/compat/freebsd32/freebsd32_misc.c
index d54e268f0930..e10f5782c10f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -709,6 +709,56 @@ freebsd32_kevent_to_kevent32(const struct kevent *kevp, 
struct kevent32 *ks32)
        }
 }
 
+void
+freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
+    struct kinfo_knote32 *kin32)
+{
+       memset(kin32, 0, sizeof(*kin32));
+       CP(*kin, *kin32, knt_kq_fd);
+       freebsd32_kevent_to_kevent32(&kin->knt_event, &kin32->knt_event);
+       CP(*kin, *kin32, knt_status);
+       CP(*kin, *kin32, knt_extdata);
+       switch (kin->knt_extdata) {
+       case KNOTE_EXTDATA_NONE:
+               break;
+       case KNOTE_EXTDATA_VNODE:
+               CP(*kin, *kin32, knt_vnode.knt_vnode_type);
+#if BYTE_ORDER == LITTLE_ENDIAN
+               kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
+                   knt_vnode_fsid;
+               kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
+                   knt_vnode_fsid >> 32;
+               kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
+                   knt_vnode_fileid;
+               kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
+                   knt_vnode_fileid >> 32;
+#else
+               kin32->knt_vnode.knt_vnode_fsid[1] = kin->knt_vnode.
+                   knt_vnode_fsid;
+               kin32->knt_vnode.knt_vnode_fsid[0] = kin->knt_vnode.
+                   knt_vnode_fsid >> 32;
+               kin32->knt_vnode.knt_vnode_fileid[1] = kin->knt_vnode.
+                   knt_vnode_fileid;
+               kin32->knt_vnode.knt_vnode_fileid[0] = kin->knt_vnode.
+                   knt_vnode_fileid >> 32;
+#endif
+               memcpy(kin32->knt_vnode.knt_vnode_fullpath,
+                   kin->knt_vnode.knt_vnode_fullpath, PATH_MAX);
+               break;
+       case KNOTE_EXTDATA_PIPE:
+#if BYTE_ORDER == LITTLE_ENDIAN
+               kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.knt_pipe_ino;
+               kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.
+                   knt_pipe_ino >> 32;
+#else
+               kin32->knt_pipe.knt_pipe_ino[1] = kin->knt_pipe.knt_pipe_ino;
+               kin32->knt_pipe.knt_pipe_ino[0] = kin->knt_pipe.
+                   knt_pipe_ino >> 32;
+#endif
+               break;
+       }
+}
+
 /*
  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  */
diff --git a/sys/compat/freebsd32/freebsd32_util.h 
b/sys/compat/freebsd32/freebsd32_util.h
index dca61da714f0..4ac314f4391e 100644
--- a/sys/compat/freebsd32/freebsd32_util.h
+++ b/sys/compat/freebsd32/freebsd32_util.h
@@ -122,6 +122,11 @@ struct image_args;
 int freebsd32_exec_copyin_args(struct image_args *args, const char *fname,
            enum uio_seg segflg, uint32_t *argv, uint32_t *envv);
 
+struct kinfo_knote;
+struct kinfo_knote32;
+void   freebsd32_kinfo_knote_to_32(const struct kinfo_knote *kin,
+           struct kinfo_knote32 *kin32);
+
 extern int compat_freebsd_32bit;
 
 #endif /* !_COMPAT_FREEBSD32_FREEBSD32_UTIL_H_ */
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index e9808e3c6e19..c7260f6bb267 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -75,6 +75,10 @@
 #include <sys/ktrace.h>
 #endif
 #include <machine/atomic.h>
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#endif
 
 #include <vm/uma.h>
 
@@ -2873,9 +2877,12 @@ knote_status_export(int kn_status)
 
 static int
 kern_proc_kqueue_report_one(struct sbuf *s, struct proc *p,
-    int kq_fd, struct kqueue *kq, struct knote *kn)
+    int kq_fd, struct kqueue *kq, struct knote *kn, bool compat32 __unused)
 {
        struct kinfo_knote kin;
+#ifdef COMPAT_FREEBSD32
+       struct kinfo_knote32 kin32;
+#endif
        int error;
 
        if (kn->kn_status == KN_MARKER)
@@ -2889,7 +2896,13 @@ kern_proc_kqueue_report_one(struct sbuf *s, struct proc 
*p,
        KQ_UNLOCK_FLUX(kq);
        if (kn->kn_fop->f_userdump != NULL)
                (void)kn->kn_fop->f_userdump(p, kn, &kin);
-       error = sbuf_bcat(s, &kin, sizeof(kin));
+#ifdef COMPAT_FREEBSD32
+       if (compat32) {
+               freebsd32_kinfo_knote_to_32(&kin, &kin32);
+               error = sbuf_bcat(s, &kin32, sizeof(kin32));
+       } else
+#endif
+               error = sbuf_bcat(s, &kin, sizeof(kin));
        KQ_LOCK(kq);
        kn_leave_flux(kn);
        return (error);
@@ -2897,7 +2910,7 @@ kern_proc_kqueue_report_one(struct sbuf *s, struct proc 
*p,
 
 static int
 kern_proc_kqueue_report(struct sbuf *s, struct proc *p, int kq_fd,
-    struct kqueue *kq)
+    struct kqueue *kq, bool compat32)
 {
        struct knote *kn;
        int error, i;
@@ -2907,7 +2920,7 @@ kern_proc_kqueue_report(struct sbuf *s, struct proc *p, 
int kq_fd,
        for (i = 0; i < kq->kq_knlistsize; i++) {
                SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) {
                        error = kern_proc_kqueue_report_one(s, p, kq_fd,
-                           kq, kn);
+                           kq, kn, compat32);
                        if (error != 0)
                                goto out;
                }
@@ -2917,7 +2930,7 @@ kern_proc_kqueue_report(struct sbuf *s, struct proc *p, 
int kq_fd,
        for (i = 0; i <= kq->kq_knhashmask; i++) {
                SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) {
                        error = kern_proc_kqueue_report_one(s, p, kq_fd,
-                           kq, kn);
+                           kq, kn, compat32);
                        if (error != 0)
                                goto out;
                }
@@ -2936,6 +2949,7 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
        struct kqueue *kq;
        struct sbuf *s, sm;
        int error, error1, kq_fd, *name;
+       bool compat32;
 
        name = (int *)arg1;
        if ((u_int)arg2 != 2)
@@ -2944,13 +2958,6 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
        error = pget((pid_t)name[0], PGET_HOLD | PGET_CANDEBUG, &p);
        if (error != 0)
                return (error);
-#ifdef COMPAT_FREEBSD32
-       if (SV_CURPROC_FLAG(SV_ILP32)) {
-               /* XXXKIB */
-               error = EOPNOTSUPP;
-               goto out1;
-       }
-#endif
 
        td = curthread;
        kq_fd = name[1];
@@ -2968,9 +2975,14 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS)
                goto out2;
        }
        sbuf_clear_flags(s, SBUF_INCLUDENUL);
+#ifdef FREEBSD_COMPAT32
+       compat32 = SV_CURPROC_FLAG(SV_ILP32);
+#else
+       compat32 = false;
+#endif
 
        kq = fp->f_data;
-       error = kern_proc_kqueue_report(s, p, kq_fd, kq);
+       error = kern_proc_kqueue_report(s, p, kq_fd, kq, compat32);
        error1 = sbuf_finish(s);
        if (error == 0)
                error = error1;

Reply via email to