git: fa8fdd80dff9 - main - sysctl KERN_PROC_KQUEUE: implement compat32
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Mar 2025 02:24:50 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=fa8fdd80dff94dc848b449282080a5d85a3e6012 commit fa8fdd80dff94dc848b449282080a5d85a3e6012 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-03-13 23:05:21 +0000 Commit: Konstantin Belousov <kib@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;