aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-10-06 02:57:37 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-10-06 02:57:37 +0000
commitf165a1df9a8fb7bd57780b433cfb4c2cb3d1d9f4 (patch)
tree110ee564de2349179386d92c757af60b02767042 /lib
parent8741306b3b728e1289683b3508df8147ff1b4380 (diff)
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/libkvm/kvm_pcpu.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/libkvm/kvm_pcpu.c b/lib/libkvm/kvm_pcpu.c
index 2e52f5e7e8503..008a3d20129ad 100644
--- a/lib/libkvm/kvm_pcpu.c
+++ b/lib/libkvm/kvm_pcpu.c
@@ -50,15 +50,23 @@ __FBSDID("$FreeBSD$");
#include "kvm_private.h"
+#ifdef __amd64__
+#define __OFFSET_BY_PCPU
+#endif
+
static struct nlist kvm_pcpu_nl[] = {
{ .n_name = "_cpuid_to_pcpu" },
{ .n_name = "_mp_maxcpus" },
{ .n_name = "_mp_ncpus" },
+#ifdef __OFFSET_BY_PCPU
+ { .n_name = "___pcpu" },
+#endif
{ .n_name = NULL },
};
#define NL_CPUID_TO_PCPU 0
#define NL_MP_MAXCPUS 1
#define NL_MP_NCPUS 2
+#define NL___PCPU 3
/*
* Kernel per-CPU data state. We cache this stuff on the first
@@ -71,6 +79,9 @@ static struct nlist kvm_pcpu_nl[] = {
static void **pcpu_data;
static int maxcpu;
static int mp_ncpus;
+#ifdef __OFFSET_BY_PCPU
+static unsigned long __pcpu;
+#endif
static int
_kvm_pcpu_init(kvm_t *kd)
@@ -103,6 +114,17 @@ _kvm_pcpu_init(kvm_t *kd)
_kvm_err(kd, kd->program, "cannot read mp_ncpus");
return (-1);
}
+#ifdef __OFFSET_BY_PCPU
+ if (kvm_pcpu_nl[NL___PCPU].n_value == 0) {
+ _kvm_err(kd, kd->program, "unable to find __pcpu");
+ return (-1);
+ }
+ if (kvm_read(kd, kvm_pcpu_nl[NL___PCPU].n_value, &__pcpu,
+ sizeof(__pcpu)) != sizeof(__pcpu)) {
+ _kvm_err(kd, kd->program, "cannot read __pcpu");
+ return (-1);
+ }
+#endif
len = max * sizeof(void *);
data = malloc(len);
if (data == NULL) {
@@ -329,6 +351,13 @@ kvm_read_zpcpu(kvm_t *kd, u_long base, void *buf, size_t size, int cpu)
if (!kvm_native(kd))
return (-1);
+ if (mp_ncpus == 0)
+ if (_kvm_pcpu_init(kd) < 0)
+ return (0);
+
+#ifdef __OFFSET_BY_PCPU
+ base += __pcpu;
+#endif
return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu),
buf, size));
}