summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c10
-rw-r--r--sys/kern/kern_exec.c8
-rw-r--r--sys/kern/kern_sysctl.c38
-rw-r--r--sys/kern/kern_tc.c19
-rw-r--r--sys/kern/kern_xxx.c10
-rw-r--r--sys/sys/sysctl.h12
-rw-r--r--sys/vm/vm_meter.c20
7 files changed, 84 insertions, 33 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index b78f552..0326242 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1203,25 +1203,21 @@ freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
return (EINVAL);
-
- error = copyin(uap->name, &name, uap->namelen * sizeof(int));
+ error = copyin(uap->name, name, uap->namelen * sizeof(int));
if (error)
return (error);
-
mtx_lock(&Giant);
-
if (uap->oldlenp)
oldlen = fuword32(uap->oldlenp);
else
oldlen = 0;
error = userland_sysctl(td, name, uap->namelen,
uap->old, &oldlen, 1,
- uap->new, uap->newlen, &j);
+ uap->new, uap->newlen, &j, SCTL_MASK32);
if (error && error != ENOMEM)
goto done2;
- if (uap->oldlenp) {
+ if (uap->oldlenp)
suword32(uap->oldlenp, j);
- }
done2:
mtx_unlock(&Giant);
return (error);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index d236832..06cbc68 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -104,8 +104,8 @@ sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS)
int error;
p = curproc;
-#if defined(__amd64__) || defined(__ia64__)
- if (req->oldlen == sizeof(unsigned int)) {
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
unsigned int val;
val = (unsigned int)p->p_sysent->sv_psstrings;
error = SYSCTL_OUT(req, &val, sizeof(val));
@@ -123,8 +123,8 @@ sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS)
int error;
p = curproc;
-#if defined(__amd64__) || defined(__ia64__)
- if (req->oldlen == sizeof(unsigned int)) {
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
unsigned int val;
val = (unsigned int)p->p_sysent->sv_usrstack;
error = SYSCTL_OUT(req, &val, sizeof(val));
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index eda6810..af0dda4 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -828,20 +828,35 @@ int
sysctl_handle_long(SYSCTL_HANDLER_ARGS)
{
int error = 0;
- long tmpout;
+ long tmplong;
+#ifdef SCTL_MASK32
+ int tmpint;
+#endif
/*
* Attempt to get a coherent snapshot by making a copy of the data.
*/
if (!arg1)
return (EINVAL);
- tmpout = *(long *)arg1;
- error = SYSCTL_OUT(req, &tmpout, sizeof(long));
+ tmplong = *(long *)arg1;
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
+ tmpint = tmplong;
+ error = SYSCTL_OUT(req, &tmpint, sizeof(int));
+ } else
+#endif
+ error = SYSCTL_OUT(req, &tmplong, sizeof(long));
if (error || !req->newptr)
return (error);
- error = SYSCTL_IN(req, arg1, sizeof(long));
+#ifdef SCTL_MASK32
+ if (req->flags & SCTL_MASK32) {
+ error = SYSCTL_IN(req, &tmpint, sizeof(int));
+ *(long *)arg1 = (long)tmpint;
+ } else
+#endif
+ error = SYSCTL_IN(req, arg1, sizeof(long));
return (error);
}
@@ -965,7 +980,7 @@ sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
int
kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, void *new, size_t newlen, size_t *retval)
+ size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags)
{
int error = 0;
struct sysctl_req req;
@@ -973,6 +988,7 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
bzero(&req, sizeof req);
req.td = td;
+ req.flags = flags;
if (oldlenp) {
req.oldlen = *oldlenp;
@@ -1015,7 +1031,7 @@ kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
int
kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
- void *new, size_t newlen, size_t *retval)
+ void *new, size_t newlen, size_t *retval, int flags)
{
int oid[CTL_MAXNAME];
size_t oidlen, plen;
@@ -1026,12 +1042,12 @@ kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
oidlen = sizeof(oid);
error = kernel_sysctl(td, oid, 2, oid, &oidlen,
- (void *)name, strlen(name), &plen);
+ (void *)name, strlen(name), &plen, flags);
if (error)
return (error);
error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
- new, newlen, retval);
+ new, newlen, retval, flags);
return (error);
}
@@ -1256,7 +1272,7 @@ __sysctl(struct thread *td, struct sysctl_args *uap)
error = userland_sysctl(td, name, uap->namelen,
uap->old, uap->oldlenp, 0,
- uap->new, uap->newlen, &j);
+ uap->new, uap->newlen, &j, 0);
if (error && error != ENOMEM)
goto done2;
if (uap->oldlenp) {
@@ -1275,7 +1291,8 @@ done2:
*/
int
userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
- size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval)
+ size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval,
+ int flags)
{
int error = 0;
struct sysctl_req req;
@@ -1283,6 +1300,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
bzero(&req, sizeof req);
req.td = td;
+ req.flags = flags;
if (oldlenp) {
if (inkernel) {
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 984d237..4567dde 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -92,8 +92,9 @@ time_t time_uptime = 0;
static struct bintime boottimebin;
struct timeval boottime;
-SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, CTLFLAG_RD,
- &boottime, timeval, "System boottime");
+static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD,
+ NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime");
SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, "");
@@ -116,6 +117,20 @@ TC_STATS(nsetclock);
static void tc_windup(void);
+static int
+sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
+{
+#ifdef SCTL_MASK32
+ int tv[2];
+
+ if (req->flags & SCTL_MASK32) {
+ tv[0] = boottime.tv_sec;
+ tv[1] = boottime.tv_usec;
+ return SYSCTL_OUT(req, tv, sizeof(tv));
+ } else
+#endif
+ return SYSCTL_OUT(req, &boottime, sizeof(boottime));
+}
/*
* Return the difference between the timehands' counter value now and what
* was when we copied it to the timehands' offset_count.
diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c
index 6840e64..fdf6e27 100644
--- a/sys/kern/kern_xxx.c
+++ b/sys/kern/kern_xxx.c
@@ -192,7 +192,7 @@ uname(td, uap)
len = sizeof (uap->name->sysname);
mtx_lock(&Giant);
error = userland_sysctl(td, name, 2, uap->name->sysname, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->sysname + sizeof(uap->name->sysname) - 1, 0);
@@ -200,7 +200,7 @@ uname(td, uap)
name[1] = KERN_HOSTNAME;
len = sizeof uap->name->nodename;
error = userland_sysctl(td, name, 2, uap->name->nodename, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->nodename + sizeof(uap->name->nodename) - 1, 0);
@@ -208,7 +208,7 @@ uname(td, uap)
name[1] = KERN_OSRELEASE;
len = sizeof uap->name->release;
error = userland_sysctl(td, name, 2, uap->name->release, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->release + sizeof(uap->name->release) - 1, 0);
@@ -217,7 +217,7 @@ uname(td, uap)
name = KERN_VERSION;
len = sizeof uap->name->version;
error = userland_sysctl(td, name, 2, uap->name->version, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->version + sizeof(uap->name->version) - 1, 0);
@@ -241,7 +241,7 @@ uname(td, uap)
name[1] = HW_MACHINE;
len = sizeof uap->name->machine;
error = userland_sysctl(td, name, 2, uap->name->machine, &len,
- 1, 0, 0, 0);
+ 1, 0, 0, 0, 0);
if (error)
goto done2;
subyte( uap->name->machine + sizeof(uap->name->machine) - 1, 0);
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 1431f64..bea64dd 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -120,6 +120,11 @@ struct ctlname {
#define REQ_LOCKED 1 /* locked and not wired */
#define REQ_WIRED 2 /* locked and wired */
+/* definitions for sysctl_req 'flags' member */
+#if defined(__amd64__) || defined(__ia64__)
+#define SCTL_MASK32 1 /* 32 bit emulation */
+#endif
+
/*
* This describes the access space for a sysctl request. This is needed
* so that we can use the interface from the kernel or from user-space.
@@ -136,6 +141,7 @@ struct sysctl_req {
size_t newidx;
int (*newfunc)(struct sysctl_req *, void *, size_t);
size_t validlen;
+ int flags;
};
SLIST_HEAD(sysctl_oid_list, sysctl_oid);
@@ -617,13 +623,13 @@ int sysctl_ctx_entry_del(struct sysctl_ctx_list *clist,
int kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *oldlenp, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int kernel_sysctlbyname(struct thread *td, char *name,
void *old, size_t *oldlenp, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
size_t *oldlenp, int inkernel, void *new, size_t newlen,
- size_t *retval);
+ size_t *retval, int flags);
int sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
int *nindx, struct sysctl_req *req);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index 4c09acd..4c3d60b 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -85,8 +85,24 @@ SYSCTL_UINT(_vm, VM_V_PAGEOUT_FREE_MIN, v_pageout_free_min,
SYSCTL_UINT(_vm, OID_AUTO, v_free_severe,
CTLFLAG_RW, &cnt.v_free_severe, 0, "");
-SYSCTL_STRUCT(_vm, VM_LOADAVG, loadavg, CTLFLAG_RD,
- &averunnable, loadavg, "Machine loadaverage history");
+static int
+sysctl_vm_loadavg(SYSCTL_HANDLER_ARGS)
+{
+#ifdef SCTL_MASK32
+ u_int32_t la[4];
+
+ if (req->flags & SCTL_MASK32) {
+ la[0] = averunnable.ldavg[0];
+ la[1] = averunnable.ldavg[1];
+ la[2] = averunnable.ldavg[2];
+ la[3] = averunnable.fscale;
+ return SYSCTL_OUT(req, la, sizeof(la));
+ } else
+#endif
+ return SYSCTL_OUT(req, &averunnable, sizeof(averunnable));
+}
+SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD,
+ NULL, 0, sysctl_vm_loadavg, "S,loadavg", "Machine loadaverage history");
static int
vmtotal(SYSCTL_HANDLER_ARGS)
OpenPOWER on IntegriCloud