The branch main has been updated by des:

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

commit a11d132f6c62f32abe44b19f7527d97ddc239058
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-01-26 12:01:39 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-01-26 12:01:59 +0000

    devstat: Provide 32-bit compatibility
    
    If a 32-bit process running on a 64-bit kernel requests kern.devstat.all,
    translate each struct devstat to its 32-bit equivalent before copying it
    out.
    
    Also fix a bug where an early error would be ignored if there were no
    devices to report.
    
    MFC after:      1 week
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D54591
---
 sys/compat/freebsd32/freebsd32.h | 27 +++++++++++++++++++
 sys/kern/subr_devstat.c          | 56 +++++++++++++++++++++++++++++++++++-----
 2 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index 7d21a5be5570..a8d54290980d 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -29,7 +29,10 @@
 #ifndef _COMPAT_FREEBSD32_FREEBSD32_H_
 #define _COMPAT_FREEBSD32_FREEBSD32_H_
 
+#include <sys/cdefs.h>
 #include <sys/abi_compat.h>
+#include <sys/devicestat.h>
+#include <sys/mount.h>
 #include <sys/procfs.h>
 #include <sys/socket.h>
 #include <sys/user.h>
@@ -540,4 +543,28 @@ struct ptrace_sc_remote32 {
        uint32_t        pscr_args;
 };
 
+struct devstat32 {
+       u_int                   sequence0;
+       int                     allocated;
+       u_int                   start_count;
+       u_int                   end_count;
+       struct bintime32        busy_from;
+       struct { u_int32_t stqe_next; } dev_links;
+       u_int32_t               device_number;
+       char                    device_name[DEVSTAT_NAME_LEN];
+       int                     unit_number;
+       freebsd32_uint64_t      bytes[DEVSTAT_N_TRANS_FLAGS];
+       freebsd32_uint64_t      operations[DEVSTAT_N_TRANS_FLAGS];
+       struct bintime32        duration[DEVSTAT_N_TRANS_FLAGS];
+       struct bintime32        busy_time;
+       struct bintime32        creation_time;
+       u_int32_t               block_size;
+       freebsd32_uint64_t      tag_types[3];
+       devstat_support_flags   flags;
+       devstat_type_flags      device_type;
+       devstat_priority        priority;
+       u_int32_t               id;
+       u_int                   sequence1;
+};
+
 #endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
diff --git a/sys/kern/subr_devstat.c b/sys/kern/subr_devstat.c
index c4d0223d484f..c62df0e210e1 100644
--- a/sys/kern/subr_devstat.c
+++ b/sys/kern/subr_devstat.c
@@ -43,6 +43,10 @@
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
+#ifdef COMPAT_FREEBSD32
+#include <compat/freebsd32/freebsd32.h>
+#endif
+
 #include <machine/atomic.h>
 
 SDT_PROVIDER_DEFINE(io);
@@ -398,25 +402,63 @@ sysctl_devstat(SYSCTL_HANDLER_ARGS)
         */
        mygen = devstat_generation;
 
-       error = SYSCTL_OUT(req, &mygen, sizeof(mygen));
-
-       if (devstat_num_devs == 0)
-               return(0);
+#ifdef COMPAT_FREEBSD32
+       if ((req->flags & SCTL_MASK32) != 0) {
+               int32_t mygen32 = (int32_t)mygen;
 
+               error = SYSCTL_OUT(req, &mygen32, sizeof(mygen32));
+       } else
+#endif /* COMPAT_FREEBSD32 */
+               error = SYSCTL_OUT(req, &mygen, sizeof(mygen));
        if (error != 0)
                return (error);
 
+       if (devstat_num_devs == 0)
+               return(0);
+
        mtx_lock(&devstat_mutex);
        nds = STAILQ_FIRST(&device_statq); 
        if (mygen != devstat_generation)
                error = EBUSY;
        mtx_unlock(&devstat_mutex);
-
        if (error != 0)
                return (error);
 
        while (nds != NULL) {
-               error = SYSCTL_OUT(req, nds, sizeof(struct devstat));
+#ifdef COMPAT_FREEBSD32
+               if ((req->flags & SCTL_MASK32) != 0) {
+                       struct devstat32 ds32;
+                       unsigned int i;
+
+                       CP(*nds, ds32, sequence0);
+                       CP(*nds, ds32, allocated);
+                       CP(*nds, ds32, start_count);
+                       CP(*nds, ds32, end_count);
+                       BT_CP(*nds, ds32, busy_from);
+                       PTROUT_CP(*nds, ds32, dev_links.stqe_next);
+                       CP(*nds, ds32, device_number);
+                       strcpy(ds32.device_name, nds->device_name);
+                       CP(*nds, ds32, unit_number);
+                       for (i = 0; i < DEVSTAT_N_TRANS_FLAGS; i++) {
+                               FU64_CP(*nds, ds32, bytes[i]);
+                               FU64_CP(*nds, ds32, operations[i]);
+                               BT_CP(*nds, ds32, duration[i]);
+                       }
+                       BT_CP(*nds, ds32, busy_time);
+                       BT_CP(*nds, ds32, creation_time);
+                       CP(*nds, ds32, block_size);
+                       for (i = 0; i < nitems(ds32.tag_types); i++) {
+                               FU64_CP(*nds, ds32, tag_types[i]);
+                       }
+                       CP(*nds, ds32, flags);
+                       CP(*nds, ds32, device_type);
+                       CP(*nds, ds32, priority);
+                       PTROUT_CP(*nds, ds32, id);
+                       CP(*nds, ds32, sequence1);
+                       error = SYSCTL_OUT(req, &ds32, sizeof(ds32));
+               } else
+#endif /* COMPAT_FREEBSD32 */
+                       error = SYSCTL_OUT(req, nds, sizeof(*nds));
                if (error != 0)
                        return (error);
                mtx_lock(&devstat_mutex);
@@ -428,7 +470,7 @@ sysctl_devstat(SYSCTL_HANDLER_ARGS)
                if (error != 0)
                        return (error);
        }
-       return(error);
+       return (error);
 }
 
 /*

Reply via email to