summaryrefslogtreecommitdiffstats
path: root/lib/libkvm
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2014-04-27 08:13:43 +0000
committersjg <sjg@FreeBSD.org>2014-04-27 08:13:43 +0000
commit0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e (patch)
treeb92e741b68057a24e381faa9809f32030d65574c /lib/libkvm
parentc244fcbcaa61dc2a15995e7dbdf3ae8107bc2111 (diff)
parent69c3e6933b6946c49fe99b19986f018d71621980 (diff)
downloadFreeBSD-src-0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e.zip
FreeBSD-src-0c7e03a54c8e7ddc9c3fe710f83d9ca53173692e.tar.gz
Merge head
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/Makefile23
-rw-r--r--lib/libkvm/kvm.c39
-rw-r--r--lib/libkvm/kvm.h3
-rw-r--r--lib/libkvm/kvm_arm.c6
-rw-r--r--lib/libkvm/kvm_getpcpu.310
-rw-r--r--lib/libkvm/kvm_ia64.c233
-rw-r--r--lib/libkvm/kvm_minidump_amd64.c4
-rw-r--r--lib/libkvm/kvm_minidump_arm.c8
-rw-r--r--lib/libkvm/kvm_pcpu.c14
9 files changed, 252 insertions, 88 deletions
diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile
index f21a1bf..4608254 100644
--- a/lib/libkvm/Makefile
+++ b/lib/libkvm/Makefile
@@ -1,23 +1,36 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
# $FreeBSD$
+.if defined(TARGET_ARCH) && !defined(COMPAT_32BIT)
+KVM_XARCH=${TARGET_ARCH}
+KVM_XCPUARCH=${KVM_XARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/}
+.else
+KVM_XARCH=${MACHINE_ARCH}
+KVM_XCPUARCH=${MACHINE_CPUARCH}
+.endif
+
+.if ${KVM_XARCH} != ${MACHINE_ARCH}
+LIB= kvm-${KVM_XARCH}
+CFLAGS+=-DCROSS_LIBKVM
+.else
LIB= kvm
+.endif
+
SHLIBDIR?= /lib
SHLIB_MAJOR= 6
CFLAGS+=-DLIBC_SCCS -I${.CURDIR}
-.if exists(${.CURDIR}/kvm_${MACHINE_ARCH}.c)
-KVM_ARCH=${MACHINE_ARCH}
+.if exists(${.CURDIR}/kvm_${KVM_XARCH}.c)
+KVM_ARCH=${KVM_XARCH}
.else
-KVM_ARCH=${MACHINE_CPUARCH}
+KVM_ARCH=${KVM_XCPUARCH}
.endif
WARNS?= 3
SRCS= kvm.c kvm_${KVM_ARCH}.c kvm_cptime.c kvm_file.c kvm_getloadavg.c \
kvm_getswapinfo.c kvm_pcpu.c kvm_proc.c kvm_vnet.c
-.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
- ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips"
+.if exists(${.CURDIR}/kvm_minidump_${KVM_ARCH}.c)
SRCS+= kvm_minidump_${KVM_ARCH}.c
.endif
INCS= kvm.h
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index 9181a49..4ff62c9 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -73,9 +73,44 @@ static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94";
#include "kvm_private.h"
+#ifndef CROSS_LIBKVM
+
/* from src/lib/libc/gen/nlist.c */
int __fdnlist(int, struct nlist *);
+#define kvm_fdnlist __fdnlist
+
+#else
+
+#include <proc_service.h>
+
+static int
+kvm_fdnlist(int fd, struct nlist *list)
+{
+ psaddr_t addr;
+ ps_err_e pserr;
+ int nfail;
+
+ nfail = 0;
+ while (list->n_name != NULL && list->n_name[0] != '\0') {
+ list->n_other = 0;
+ list->n_desc = 0;
+ pserr = ps_pglobal_lookup(NULL, NULL, list->n_name, &addr);
+ if (pserr != PS_OK) {
+ nfail++;
+ list->n_value = 0;
+ list->n_type = 0;
+ } else {
+ list->n_value = addr;
+ list->n_type = N_DATA | N_EXT;
+ }
+ list++;
+ }
+ return (nfail);
+}
+
+#endif /* CROSS_LIBKVM */
+
char *
kvm_geterr(kvm_t *kd)
{
@@ -341,7 +376,7 @@ kvm_fdnlist_prefix(kvm_t *kd, struct nlist *nl, int missing, const char *prefix,
/* Do lookup on the reduced list. */
np = n;
- unresolved = __fdnlist(kd->nlfd, np);
+ unresolved = kvm_fdnlist(kd->nlfd, np);
/* Check if we could resolve further symbols and update the list. */
if (unresolved >= 0 && unresolved < missing) {
@@ -398,7 +433,7 @@ _kvm_nlist(kvm_t *kd, struct nlist *nl, int initialize)
* slow library call.
*/
if (!ISALIVE(kd)) {
- error = __fdnlist(kd->nlfd, nl);
+ error = kvm_fdnlist(kd->nlfd, nl);
if (error <= 0) /* Hard error or success. */
return (error);
diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h
index d2ee8fa..d697795 100644
--- a/lib/libkvm/kvm.h
+++ b/lib/libkvm/kvm.h
@@ -77,6 +77,7 @@ char *kvm_geterr(kvm_t *);
char *kvm_getfiles(kvm_t *, int, int, int *);
int kvm_getloadavg(kvm_t *, double [], int);
int kvm_getmaxcpu(kvm_t *);
+int kvm_getncpus(kvm_t *);
void *kvm_getpcpu(kvm_t *, int);
uint64_t kvm_counter_u64_fetch(kvm_t *, u_long);
struct kinfo_proc *
@@ -88,7 +89,7 @@ kvm_t *kvm_open
kvm_t *kvm_openfiles
(const char *, const char *, const char *, int, char *);
ssize_t kvm_read(kvm_t *, unsigned long, void *, size_t);
-ssize_t kvm_read_zpcpu(kvm_t *, void *, u_long, size_t, int);
+ssize_t kvm_read_zpcpu(kvm_t *, unsigned long, void *, size_t, int);
ssize_t kvm_write(kvm_t *, unsigned long, const void *, size_t);
__END_DECLS
diff --git a/lib/libkvm/kvm_arm.c b/lib/libkvm/kvm_arm.c
index b1274e9..d221f6a 100644
--- a/lib/libkvm/kvm_arm.c
+++ b/lib/libkvm/kvm_arm.c
@@ -42,11 +42,15 @@ __FBSDID("$FreeBSD$");
#include <sys/elf32.h>
#include <sys/mman.h>
+#ifndef CROSS_LIBKVM
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
-
#include <machine/pmap.h>
+#else
+#include "../../sys/arm/include/pte.h"
+#include "../../sys/arm/include/vmparam.h"
+#endif
#include <db.h>
#include <limits.h>
diff --git a/lib/libkvm/kvm_getpcpu.3 b/lib/libkvm/kvm_getpcpu.3
index 4087f1c..13192c2 100644
--- a/lib/libkvm/kvm_getpcpu.3
+++ b/lib/libkvm/kvm_getpcpu.3
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 11, 2013
+.Dd February 12, 2014
.Dt KVM_GETPCPU 3
.Os
.Sh NAME
@@ -47,10 +47,12 @@
.Fn kvm_dpcpu_setcpu "kvm_t *kd" "u_int cpu"
.Ft int
.Fn kvm_getmaxcpu "kvm_t *kd"
+.Ft int
+.Fn kvm_getncpus "kvm_t *kd"
.Ft void *
.Fn kvm_getpcpu "kvm_t *kd" "int cpu"
.Ft ssize_t
-.Fn kvm_read_zpcpu "kvm_t *kd" "void *buf" "u_long base" "size_t size" "int cpu"
+.Fn kvm_read_zpcpu "kvm_t *kd" "u_long base" "void *buf" "size_t size" "int cpu"
.Ft uint64_t
.Fn kvm_counter_u64_fetch "kvm_t *kd" "u_long base"
.Sh DESCRIPTION
@@ -73,6 +75,10 @@ The
function returns the maximum number of CPUs supported by the kernel.
.Pp
The
+.Fn kvm_getncpus
+function returns the current number of CPUs in the kernel.
+.Pp
+The
.Fn kvm_getpcpu
function returns a buffer holding the per-CPU data for a single CPU.
This buffer is described by the
diff --git a/lib/libkvm/kvm_ia64.c b/lib/libkvm/kvm_ia64.c
index 74e2b80..5db7e1e 100644
--- a/lib/libkvm/kvm_ia64.c
+++ b/lib/libkvm/kvm_ia64.c
@@ -32,12 +32,21 @@
#include <sys/elf64.h>
#include <sys/mman.h>
+#ifndef CROSS_LIBKVM
#include <machine/atomic.h>
#include <machine/bootinfo.h>
+#include <machine/elf.h>
#include <machine/pte.h>
+#else
+#include "../../sys/ia64/include/atomic.h"
+#include "../../sys/ia64/include/bootinfo.h"
+#include "../../sys/ia64/include/elf.h"
+#include "../../sys/ia64/include/pte.h"
+#endif
#include <kvm.h>
#include <limits.h>
+#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
@@ -55,6 +64,8 @@
#define PBVM_BASE 0x9ffc000000000000UL
#define PBVM_PGSZ (64 * 1024)
+typedef size_t (a2p_f)(kvm_t *, uint64_t, off_t *);
+
struct vmstate {
void *mmapbase;
size_t mmapsize;
@@ -62,6 +73,7 @@ struct vmstate {
u_long kptdir;
u_long *pbvm_pgtbl;
u_int pbvm_pgtblsz;
+ a2p_f *kvatop;
};
/*
@@ -70,7 +82,7 @@ struct vmstate {
* set of headers.
*/
static int
-_kvm_maphdrs(kvm_t *kd, size_t sz)
+ia64_maphdrs(kvm_t *kd, size_t sz)
{
struct vmstate *vm = kd->vmst;
@@ -91,38 +103,103 @@ _kvm_maphdrs(kvm_t *kd, size_t sz)
}
/*
- * Translate a physical memory address to a file-offset in the crash-dump.
+ * Physical core support.
*/
+
static size_t
-_kvm_pa2off(kvm_t *kd, uint64_t pa, off_t *ofs, size_t pgsz)
+phys_addr2off(kvm_t *kd, uint64_t pa, off_t *ofs, size_t pgsz)
{
- Elf64_Ehdr *e = kd->vmst->mmapbase;
- Elf64_Phdr *p = (Elf64_Phdr*)((char*)e + e->e_phoff);
- int n = e->e_phnum;
+ Elf64_Ehdr *e;
+ Elf64_Phdr *p;
+ int n;
- if (pa != REGION_ADDR(pa)) {
- _kvm_err(kd, kd->program, "internal error");
- return (0);
- }
+ if (pa != REGION_ADDR(pa))
+ goto fail;
+ e = (Elf64_Ehdr *)(kd->vmst->mmapbase);
+ n = e->e_phnum;
+ p = (Elf64_Phdr *)(void *)((uintptr_t)(void *)e + e->e_phoff);
while (n && (pa < p->p_paddr || pa >= p->p_paddr + p->p_memsz))
p++, n--;
if (n == 0)
- return (0);
+ goto fail;
*ofs = (pa - p->p_paddr) + p->p_offset;
if (pgsz == 0)
return (p->p_memsz - (pa - p->p_paddr));
return (pgsz - ((size_t)pa & (pgsz - 1)));
+
+ fail:
+ _kvm_err(kd, kd->program, "invalid physical address %#jx",
+ (uintmax_t)pa);
+ return (0);
+}
+
+static size_t
+phys_kvatop(kvm_t *kd, uint64_t va, off_t *ofs)
+{
+ struct ia64_lpte pte;
+ uint64_t pa, pgaddr, pt0addr, pt1addr;
+ size_t pgno, pgsz, pt0no, pt1no;
+
+ if (va >= REGION_BASE(6)) {
+ /* Regions 6 and 7: direct mapped. */
+ pa = REGION_ADDR(va);
+ return (phys_addr2off(kd, pa, ofs, 0));
+ } else if (va >= REGION_BASE(5)) {
+ /* Region 5: Kernel Virtual Memory. */
+ va = REGION_ADDR(va);
+ pgsz = kd->vmst->pagesize;
+ pt0no = KPTE_DIR0_INDEX(va, pgsz);
+ pt1no = KPTE_DIR1_INDEX(va, pgsz);
+ pgno = KPTE_PTE_INDEX(va, pgsz);
+ if (pt0no >= NKPTEDIR(pgsz))
+ goto fail;
+ pt0addr = kd->vmst->kptdir + (pt0no << 3);
+ if (kvm_read(kd, pt0addr, &pt1addr, 8) != 8)
+ goto fail;
+ if (pt1addr == 0)
+ goto fail;
+ pt1addr += pt1no << 3;
+ if (kvm_read(kd, pt1addr, &pgaddr, 8) != 8)
+ goto fail;
+ if (pgaddr == 0)
+ goto fail;
+ pgaddr += pgno * sizeof(pte);
+ if (kvm_read(kd, pgaddr, &pte, sizeof(pte)) != sizeof(pte))
+ goto fail;
+ if (!(pte.pte & PTE_PRESENT))
+ goto fail;
+ pa = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1));
+ return (phys_addr2off(kd, pa, ofs, pgsz));
+ } else if (va >= PBVM_BASE) {
+ /* Region 4: Pre-Boot Virtual Memory (PBVM). */
+ va -= PBVM_BASE;
+ pgsz = PBVM_PGSZ;
+ pt0no = va / pgsz;
+ if (pt0no >= (kd->vmst->pbvm_pgtblsz >> 3))
+ goto fail;
+ pt0addr = kd->vmst->pbvm_pgtbl[pt0no];
+ if (!(pt0addr & PTE_PRESENT))
+ goto fail;
+ pa = (pt0addr & PTE_PPN_MASK) + va % pgsz;
+ return (phys_addr2off(kd, pa, ofs, pgsz));
+ }
+
+ fail:
+ _kvm_err(kd, kd->program, "invalid kernel virtual address %#jx",
+ (uintmax_t)va);
+ *ofs = -1;
+ return (0);
}
static ssize_t
-_kvm_read_phys(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz)
+phys_read(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz)
{
off_t ofs;
size_t sz;
- sz = _kvm_pa2off(kd, pa, &ofs, 0);
+ sz = phys_addr2off(kd, pa, &ofs, 0);
if (sz < bufsz)
return ((ssize_t)sz);
@@ -131,6 +208,50 @@ _kvm_read_phys(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz)
return (read(kd->pmfd, buf, bufsz));
}
+/*
+ * Virtual core support (aka minidump).
+ */
+
+static size_t
+virt_addr2off(kvm_t *kd, uint64_t va, off_t *ofs, size_t pgsz)
+{
+ Elf64_Ehdr *e;
+ Elf64_Phdr *p;
+ int n;
+
+ if (va < REGION_BASE(4))
+ goto fail;
+
+ e = (Elf64_Ehdr *)(kd->vmst->mmapbase);
+ n = e->e_phnum;
+ p = (Elf64_Phdr *)(void *)((uintptr_t)(void *)e + e->e_phoff);
+ while (n && (va < p->p_vaddr || va >= p->p_vaddr + p->p_memsz))
+ p++, n--;
+ if (n == 0)
+ goto fail;
+
+ *ofs = (va - p->p_vaddr) + p->p_offset;
+ if (pgsz == 0)
+ return (p->p_memsz - (va - p->p_vaddr));
+ return (pgsz - ((size_t)va & (pgsz - 1)));
+
+ fail:
+ _kvm_err(kd, kd->program, "invalid virtual address %#jx",
+ (uintmax_t)va);
+ return (0);
+}
+
+static size_t
+virt_kvatop(kvm_t *kd, uint64_t va, off_t *ofs)
+{
+
+ return (virt_addr2off(kd, va, ofs, 0));
+}
+
+/*
+ * KVM architecture support functions.
+ */
+
void
_kvm_freevtop(kvm_t *kd)
{
@@ -160,27 +281,37 @@ _kvm_initvtop(kvm_t *kd)
return (-1);
}
+#ifndef CROSS_LIBKVM
kd->vmst->pagesize = getpagesize();
+#else
+ kd->vmst->pagesize = 8192;
+#endif
- if (_kvm_maphdrs(kd, sizeof(Elf64_Ehdr)) == -1)
+ if (ia64_maphdrs(kd, sizeof(Elf64_Ehdr)) == -1)
return (-1);
ehdr = kd->vmst->mmapbase;
hdrsz = ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum;
- if (_kvm_maphdrs(kd, hdrsz) == -1)
+ if (ia64_maphdrs(kd, hdrsz) == -1)
return (-1);
+ kd->vmst->kvatop = (ehdr->e_flags & EF_IA_64_ABSOLUTE) ?
+ phys_kvatop : virt_kvatop;
+
/*
* Load the PBVM page table. We need this to resolve PBVM addresses.
* The PBVM page table is obtained from the bootinfo structure, of
- * which the physical address is given to us in e_entry. If e_entry
- * is 0, then this is assumed to be a pre-PBVM kernel.
+ * which the address is given to us in e_entry. If e_entry is 0, then
+ * this is assumed to be a pre-PBVM kernel.
+ * Note that the address of the bootinfo structure is either physical
+ * or virtual, depending on whether the core is physical or virtual.
*/
- if (ehdr->e_entry != 0) {
- sz = _kvm_read_phys(kd, ehdr->e_entry, &bi, sizeof(bi));
+ if (ehdr->e_entry != 0 && (ehdr->e_flags & EF_IA_64_ABSOLUTE) != 0) {
+ sz = phys_read(kd, ehdr->e_entry, &bi, sizeof(bi));
if (sz != sizeof(bi)) {
_kvm_err(kd, kd->program,
- "cannot read bootinfo from PA %#lx", ehdr->e_entry);
+ "cannot read bootinfo at physical address %#jx",
+ (uintmax_t)ehdr->e_entry);
return (-1);
}
if (bi.bi_magic != BOOTINFO_MAGIC) {
@@ -193,12 +324,12 @@ _kvm_initvtop(kvm_t *kd)
return (-1);
}
kd->vmst->pbvm_pgtblsz = bi.bi_pbvm_pgtblsz;
- sz = _kvm_read_phys(kd, bi.bi_pbvm_pgtbl, kd->vmst->pbvm_pgtbl,
+ sz = phys_read(kd, bi.bi_pbvm_pgtbl, kd->vmst->pbvm_pgtbl,
bi.bi_pbvm_pgtblsz);
if (sz != bi.bi_pbvm_pgtblsz) {
_kvm_err(kd, kd->program,
- "cannot read page table from PA %#lx",
- bi.bi_pbvm_pgtbl);
+ "cannot read page table at physical address %#jx",
+ (uintmax_t)bi.bi_pbvm_pgtbl);
return (-1);
}
} else {
@@ -225,7 +356,7 @@ _kvm_initvtop(kvm_t *kd)
return (-1);
}
- if (va < REGION_BASE(6)) {
+ if (va == REGION_BASE(5)) {
_kvm_err(kd, kd->program, "kptdir is itself virtual");
return (-1);
}
@@ -237,56 +368,8 @@ _kvm_initvtop(kvm_t *kd)
int
_kvm_kvatop(kvm_t *kd, u_long va, off_t *ofs)
{
- struct ia64_lpte pte;
- uint64_t pa, pgaddr, pt0addr, pt1addr;
- size_t pgno, pgsz, pt0no, pt1no;
-
- if (va >= REGION_BASE(6)) {
- /* Regions 6 and 7: direct mapped. */
- pa = REGION_ADDR(va);
- return (_kvm_pa2off(kd, pa, ofs, 0));
- } else if (va >= REGION_BASE(5)) {
- /* Region 5: Kernel Virtual Memory. */
- va = REGION_ADDR(va);
- pgsz = kd->vmst->pagesize;
- pt0no = KPTE_DIR0_INDEX(va, pgsz);
- pt1no = KPTE_DIR1_INDEX(va, pgsz);
- pgno = KPTE_PTE_INDEX(va, pgsz);
- if (pt0no >= NKPTEDIR(pgsz))
- goto fail;
- pt0addr = kd->vmst->kptdir + (pt0no << 3);
- if (kvm_read(kd, pt0addr, &pt1addr, 8) != 8)
- goto fail;
- if (pt1addr == 0)
- goto fail;
- pt1addr += pt1no << 3;
- if (kvm_read(kd, pt1addr, &pgaddr, 8) != 8)
- goto fail;
- if (pgaddr == 0)
- goto fail;
- pgaddr += pgno * sizeof(pte);
- if (kvm_read(kd, pgaddr, &pte, sizeof(pte)) != sizeof(pte))
- goto fail;
- if (!(pte.pte & PTE_PRESENT))
- goto fail;
- pa = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1));
- return (_kvm_pa2off(kd, pa, ofs, pgsz));
- } else if (va >= PBVM_BASE) {
- /* Region 4: Pre-Boot Virtual Memory (PBVM). */
- va -= PBVM_BASE;
- pgsz = PBVM_PGSZ;
- pt0no = va / pgsz;
- if (pt0no >= (kd->vmst->pbvm_pgtblsz >> 3))
- goto fail;
- pt0addr = kd->vmst->pbvm_pgtbl[pt0no];
- if (!(pt0addr & PTE_PRESENT))
- goto fail;
- pa = (pt0addr & PTE_PPN_MASK) + va % pgsz;
- return (_kvm_pa2off(kd, pa, ofs, pgsz));
- }
+ size_t sz;
- fail:
- _kvm_err(kd, kd->program, "invalid kernel virtual address");
- *ofs = ~0UL;
- return (0);
+ sz = kd->vmst->kvatop(kd, va, ofs);
+ return ((sz > INT_MAX) ? INT_MAX : sz);
}
diff --git a/lib/libkvm/kvm_minidump_amd64.c b/lib/libkvm/kvm_minidump_amd64.c
index 8d31673..779fa97 100644
--- a/lib/libkvm/kvm_minidump_amd64.c
+++ b/lib/libkvm/kvm_minidump_amd64.c
@@ -214,6 +214,8 @@ _kvm_minidump_vatop_v1(kvm_t *kd, u_long va, off_t *pa)
if (va >= vm->hdr.kernbase) {
pteindex = (va - vm->hdr.kernbase) >> PAGE_SHIFT;
+ if (pteindex >= vm->hdr.pmapsize / sizeof(*vm->page_map))
+ goto invalid;
pte = vm->page_map[pteindex];
if (((u_long)pte & PG_V) == 0) {
_kvm_err(kd, kd->program, "_kvm_vatop: pte not valid");
@@ -264,6 +266,8 @@ _kvm_minidump_vatop(kvm_t *kd, u_long va, off_t *pa)
if (va >= vm->hdr.kernbase) {
pdeindex = (va - vm->hdr.kernbase) >> PDRSHIFT;
+ if (pdeindex >= vm->hdr.pmapsize / sizeof(*vm->page_map))
+ goto invalid;
pde = vm->page_map[pdeindex];
if (((u_long)pde & PG_V) == 0) {
_kvm_err(kd, kd->program, "_kvm_vatop: pde not valid");
diff --git a/lib/libkvm/kvm_minidump_arm.c b/lib/libkvm/kvm_minidump_arm.c
index f6147d0..f4ba604 100644
--- a/lib/libkvm/kvm_minidump_arm.c
+++ b/lib/libkvm/kvm_minidump_arm.c
@@ -34,7 +34,9 @@ __FBSDID("$FreeBSD$");
*/
#include <sys/param.h>
+#ifndef CROSS_LIBKVM
#include <sys/user.h>
+#endif
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/mman.h>
@@ -45,12 +47,18 @@ __FBSDID("$FreeBSD$");
#include <nlist.h>
#include <kvm.h>
+#ifndef CROSS_LIBKVM
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <machine/elf.h>
#include <machine/cpufunc.h>
#include <machine/minidump.h>
+#else
+#include "../../sys/arm/include/pte.h"
+#include "../../sys/arm/include/vmparam.h"
+#include "../../sys/arm/include/minidump.h"
+#endif
#include <limits.h>
diff --git a/lib/libkvm/kvm_pcpu.c b/lib/libkvm/kvm_pcpu.c
index 2d7fb41..662566a 100644
--- a/lib/libkvm/kvm_pcpu.c
+++ b/lib/libkvm/kvm_pcpu.c
@@ -173,6 +173,16 @@ kvm_getmaxcpu(kvm_t *kd)
return (maxcpu);
}
+int
+kvm_getncpus(kvm_t *kd)
+{
+
+ if (mp_ncpus == 0)
+ if (_kvm_pcpu_init(kd) < 0)
+ return (-1);
+ return (mp_ncpus);
+}
+
static int
_kvm_dpcpu_setcpu(kvm_t *kd, u_int cpu, int report_error)
{
@@ -306,7 +316,7 @@ kvm_dpcpu_setcpu(kvm_t *kd, u_int cpu)
* Obtain a per-CPU copy for given cpu from UMA_ZONE_PCPU allocation.
*/
ssize_t
-kvm_read_zpcpu(kvm_t *kd, void *buf, u_long base, size_t size, int cpu)
+kvm_read_zpcpu(kvm_t *kd, u_long base, void *buf, size_t size, int cpu)
{
return (kvm_read(kd, (uintptr_t)(base + sizeof(struct pcpu) * cpu),
@@ -327,7 +337,7 @@ kvm_counter_u64_fetch(kvm_t *kd, u_long base)
r = 0;
for (int i = 0; i < mp_ncpus; i++) {
- if (kvm_read_zpcpu(kd, &c, base, sizeof(c), i) != sizeof(c))
+ if (kvm_read_zpcpu(kd, base, &c, sizeof(c), i) != sizeof(c))
return (0);
r += c;
}
OpenPOWER on IntegriCloud