summaryrefslogtreecommitdiffstats
path: root/lib/libkvm
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-27 15:50:14 +0000
committerattilio <attilio@FreeBSD.org>2011-05-27 15:50:14 +0000
commit9a75ededfbf8db715ecf5af60beb219e832c77da (patch)
tree68f6ee4e9db6eec8c42d7d11015ac86f5fc6e7df /lib/libkvm
parent867c6223e7e4f6682389d40926782fd537ffc3ad (diff)
downloadFreeBSD-src-9a75ededfbf8db715ecf5af60beb219e832c77da.zip
FreeBSD-src-9a75ededfbf8db715ecf5af60beb219e832c77da.tar.gz
In the near future cpuset_t objects in struct pcpu will be axed out, but
as long as this does not happen, we need to fix interfaces to userland in order to not break run-time accesses to the structure. Reviwed by: kib Tested by: pluknet
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm_pcpu.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/libkvm/kvm_pcpu.c b/lib/libkvm/kvm_pcpu.c
index fd09fc8..bc73baf 100644
--- a/lib/libkvm/kvm_pcpu.c
+++ b/lib/libkvm/kvm_pcpu.c
@@ -39,11 +39,13 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/cpuset.h>
#include <sys/pcpu.h>
#include <sys/sysctl.h>
#include <kvm.h>
#include <limits.h>
#include <stdlib.h>
+#include <unistd.h>
#include "kvm_private.h"
@@ -118,6 +120,9 @@ _kvm_pcpu_clear(void)
void *
kvm_getpcpu(kvm_t *kd, int cpu)
{
+ long kcpusetsize;
+ ssize_t nbytes;
+ uintptr_t readptr;
char *buf;
if (kd == NULL) {
@@ -125,6 +130,10 @@ kvm_getpcpu(kvm_t *kd, int cpu)
return (NULL);
}
+ kcpusetsize = sysconf(_SC_CPUSET_SIZE);
+ if (kcpusetsize == -1 || (u_long)kcpusetsize > sizeof(cpuset_t))
+ return ((void *)-1);
+
if (maxcpu == 0)
if (_kvm_pcpu_init(kd) < 0)
return ((void *)-1);
@@ -137,8 +146,26 @@ kvm_getpcpu(kvm_t *kd, int cpu)
_kvm_err(kd, kd->program, "out of memory");
return ((void *)-1);
}
- if (kvm_read(kd, (uintptr_t)pcpu_data[cpu], buf, sizeof(struct pcpu)) !=
- sizeof(struct pcpu)) {
+ nbytes = sizeof(struct pcpu) - 2 * kcpusetsize;
+ readptr = (uintptr_t)pcpu_data[cpu];
+ if (kvm_read(kd, readptr, buf, nbytes) != nbytes) {
+ _kvm_err(kd, kd->program, "unable to read per-CPU data");
+ free(buf);
+ return ((void *)-1);
+ }
+
+ /* Fetch the valid cpuset_t objects. */
+ CPU_ZERO((cpuset_t *)(buf + nbytes));
+ CPU_ZERO((cpuset_t *)(buf + nbytes + sizeof(cpuset_t)));
+ readptr += nbytes;
+ if (kvm_read(kd, readptr, buf + nbytes, kcpusetsize) != kcpusetsize) {
+ _kvm_err(kd, kd->program, "unable to read per-CPU data");
+ free(buf);
+ return ((void *)-1);
+ }
+ readptr += kcpusetsize;
+ if (kvm_read(kd, readptr, buf + nbytes + sizeof(cpuset_t),
+ kcpusetsize) != kcpusetsize) {
_kvm_err(kd, kd->program, "unable to read per-CPU data");
free(buf);
return ((void *)-1);
OpenPOWER on IntegriCloud