libkvm: catch up with pre-subtracated per-cpu addresses
Only concerns amd64. Reported by: imp
This commit is contained in:
parent
8741306b3b
commit
f165a1df9a
@ -50,15 +50,23 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include "kvm_private.h"
|
#include "kvm_private.h"
|
||||||
|
|
||||||
|
#ifdef __amd64__
|
||||||
|
#define __OFFSET_BY_PCPU
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct nlist kvm_pcpu_nl[] = {
|
static struct nlist kvm_pcpu_nl[] = {
|
||||||
{ .n_name = "_cpuid_to_pcpu" },
|
{ .n_name = "_cpuid_to_pcpu" },
|
||||||
{ .n_name = "_mp_maxcpus" },
|
{ .n_name = "_mp_maxcpus" },
|
||||||
{ .n_name = "_mp_ncpus" },
|
{ .n_name = "_mp_ncpus" },
|
||||||
|
#ifdef __OFFSET_BY_PCPU
|
||||||
|
{ .n_name = "___pcpu" },
|
||||||
|
#endif
|
||||||
{ .n_name = NULL },
|
{ .n_name = NULL },
|
||||||
};
|
};
|
||||||
#define NL_CPUID_TO_PCPU 0
|
#define NL_CPUID_TO_PCPU 0
|
||||||
#define NL_MP_MAXCPUS 1
|
#define NL_MP_MAXCPUS 1
|
||||||
#define NL_MP_NCPUS 2
|
#define NL_MP_NCPUS 2
|
||||||
|
#define NL___PCPU 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel per-CPU data state. We cache this stuff on the first
|
* 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 void **pcpu_data;
|
||||||
static int maxcpu;
|
static int maxcpu;
|
||||||
static int mp_ncpus;
|
static int mp_ncpus;
|
||||||
|
#ifdef __OFFSET_BY_PCPU
|
||||||
|
static unsigned long __pcpu;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_kvm_pcpu_init(kvm_t *kd)
|
_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");
|
_kvm_err(kd, kd->program, "cannot read mp_ncpus");
|
||||||
return (-1);
|
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 *);
|
len = max * sizeof(void *);
|
||||||
data = malloc(len);
|
data = malloc(len);
|
||||||
if (data == NULL) {
|
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))
|
if (!kvm_native(kd))
|
||||||
return (-1);
|
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),
|
return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu),
|
||||||
buf, size));
|
buf, size));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user