Latest revision of the netbsd32 swapctl patch I noted david@ suggestion to rework uvm_swap_stats() to add a callback, but I am not sure it is worth it. This is just the emulation path for a rarely used code path. I can work on it if the consensus is that it is the way to go, though.
Index: sys/compat/netbsd32/netbsd32_netbsd.c =================================================================== RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_netbsd.c,v retrieving revision 1.179 diff -U 4 -r1.179 netbsd32_netbsd.c --- sys/compat/netbsd32/netbsd32_netbsd.c 1 Feb 2012 05:43:54 -0000 1.179 +++ sys/compat/netbsd32/netbsd32_netbsd.c 2 Feb 2014 04:31:02 -0000 @@ -55,8 +55,9 @@ #include <sys/sockio.h> #include <sys/socketvar.h> #include <sys/mbuf.h> #include <sys/stat.h> +#include <sys/swap.h> #include <sys/time.h> #include <sys/signalvar.h> #include <sys/ptrace.h> #include <sys/ktrace.h> @@ -72,8 +73,9 @@ #include <sys/kauth.h> #include <sys/vfs_syscalls.h> #include <uvm/uvm_extern.h> +#include <uvm/uvm_swap.h> #include <sys/sa.h> #include <sys/savar.h> #include <sys/syscallargs.h> @@ -1727,8 +1729,48 @@ NETBSD32TOP_UAP(to, const char); return (sys___posix_rename(l, &ua, retval)); } +static int +netbsd32_swapctl_stats(struct lwp *l, struct sys_swapctl_args *uap, register_t *retval) +{ + struct swapent *sep; + struct netbsd32_swapent *sep32; + int count = SCARG(uap, misc); + int i, error = 0; + + /* Make sure userland cannot exhaust kernel memory */ + if ((size_t)count > (size_t)uvmexp.nswapdev) + count = uvmexp.nswapdev; + + sep = kmem_alloc(sizeof(*sep) * count, KM_SLEEP); + sep32 = kmem_alloc(sizeof(*sep32) * count, KM_SLEEP); + + uvm_swap_stats(SWAP_STATS, sep, count, retval); + count = *retval; + + if (count < 1) + goto out; + + for (i = 0; i < count; i++) { + sep32[i].se_dev = sep[i].se_dev; + sep32[i].se_flags = sep[i].se_flags; + sep32[i].se_nblks = sep[i].se_nblks; + sep32[i].se_inuse = sep[i].se_inuse; + sep32[i].se_priority = sep[i].se_priority; + memcpy(sep32[i].se_path, sep[i].se_path, + sizeof(sep32[i].se_path)); + } + + error = copyout(sep32, SCARG(uap, arg), sizeof(*sep32) * count); + +out: + kmem_free(sep, sizeof(*sep)); + kmem_free(sep32, sizeof(*sep32)); + + return error; +} + int netbsd32_swapctl(struct lwp *l, const struct netbsd32_swapctl_args *uap, register_t *retval) { /* { @@ -1740,8 +1782,13 @@ NETBSD32TO64_UAP(cmd); NETBSD32TOP_UAP(arg, void); NETBSD32TO64_UAP(misc); + + /* SWAP_STATS50 and SWAP_STATS13 structures need no translation */ + if (SCARG(&ua, cmd) == SWAP_STATS) + return netbsd32_swapctl_stats(l, &ua, retval); + return (sys_swapctl(l, &ua, retval)); } int Index: sys/uvm/uvm_swap.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_swap.c,v retrieving revision 1.161 diff -U 4 -r1.161 uvm_swap.c --- sys/uvm/uvm_swap.c 5 Feb 2012 16:08:28 -0000 1.161 +++ sys/uvm/uvm_swap.c 2 Feb 2014 04:31:02 -0000 @@ -236,10 +236,8 @@ static int swap_on(struct lwp *, struct swapdev *); static int swap_off(struct lwp *, struct swapdev *); -static void uvm_swap_stats(int, struct swapent *, int, register_t *); - static void sw_reg_strategy(struct swapdev *, struct buf *, int); static void sw_reg_biodone(struct buf *); static void sw_reg_iodone(struct work *wk, void *dummy); static void sw_reg_start(struct swapdev *); @@ -733,9 +731,9 @@ * copying the swapent array to the stackgap, and this array's size * is not known at build time. Hence it would not be possible to * ensure it would fit in the stackgap in any case. */ -static void +void uvm_swap_stats(int cmd, struct swapent *sep, int sec, register_t *retval) { struct swappri *spp; struct swapdev *sdp; Index: sys/uvm/uvm_swap.h =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_swap.h,v retrieving revision 1.18 diff -U 4 -r1.18 uvm_swap.h --- sys/uvm/uvm_swap.h 27 Apr 2011 00:35:52 -0000 1.18 +++ sys/uvm/uvm_swap.h 2 Feb 2014 04:31:02 -0000 @@ -46,10 +46,12 @@ int uvm_swap_alloc(int *, bool); void uvm_swap_free(int, int); void uvm_swap_markbad(int, int); bool uvm_swapisfull(void); +void uvm_swap_stats(int, struct swapent *, int, register_t *); #else /* defined(VMSWAP) */ #define uvm_swapisfull() true +#define uvm_swap_stats(c, sep, count, retval) { *retval = 0; } #endif /* defined(VMSWAP) */ #endif /* _KERNEL */ -- Emmanuel Dreyfus m...@netbsd.org