Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libkvm/kvm_private.c
Show First 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | _kvm_map_get(kvm_t *kd, u_long pa, unsigned int page_size) | ||||
addr = (uintptr_t)kd->page_map + off; | addr = (uintptr_t)kd->page_map + off; | ||||
if (off >= kd->pt_sparse_off) | if (off >= kd->pt_sparse_off) | ||||
addr = (uintptr_t)kd->sparse_map + (off - kd->pt_sparse_off); | addr = (uintptr_t)kd->sparse_map + (off - kd->pt_sparse_off); | ||||
return (void *)addr; | return (void *)addr; | ||||
} | } | ||||
int | int | ||||
_kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off, | _kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off, | ||||
size_t map_len, off_t map_off, off_t sparse_off, int page_size, | size_t map_len, off_t map_off, off_t sparse_off, int page_size) | ||||
int word_size) | |||||
{ | { | ||||
uint64_t *addr; | uint64_t *addr; | ||||
uint32_t *popcount_bin; | uint32_t *popcount_bin; | ||||
int bin_popcounts = 0; | int bin_popcounts = 0; | ||||
uint64_t pc_bins, res; | uint64_t pc_bins, res; | ||||
ssize_t rd; | ssize_t rd; | ||||
kd->dump_avail_size = dump_avail_size; | kd->dump_avail_size = dump_avail_size; | ||||
if (dump_avail_size > 0) { | if (dump_avail_size > 0) { | ||||
kd->dump_avail = mmap(NULL, kd->dump_avail_size, PROT_READ, | kd->dump_avail = mmap(NULL, kd->dump_avail_size, PROT_READ, | ||||
MAP_PRIVATE, kd->pmfd, dump_avail_off); | MAP_PRIVATE, kd->pmfd, dump_avail_off); | ||||
} else { | } else { | ||||
/* | /* | ||||
* Older version minidumps don't provide dump_avail[], | * Older version minidumps don't provide dump_avail[], | ||||
* so the bitmap is fully populated from 0 to | * so the bitmap is fully populated from 0 to | ||||
* last_pa. Create an implied dump_avail that | * last_pa. Create an implied dump_avail that | ||||
* expresses this. | * expresses this. | ||||
*/ | */ | ||||
kd->dump_avail = calloc(4, word_size); | kd->dump_avail = calloc(4, sizeof(uint64_t)); | ||||
if (word_size == sizeof(uint32_t)) { | kd->dump_avail[1] = _kvm64toh(kd, map_len * 8 * page_size); | ||||
((uint32_t *)kd->dump_avail)[1] = _kvm32toh(kd, | |||||
map_len * 8 * page_size); | |||||
} else { | |||||
kd->dump_avail[1] = _kvm64toh(kd, | |||||
map_len * 8 * page_size); | |||||
} | } | ||||
} | |||||
/* | /* | ||||
* Map the bitmap specified by the arguments. | * Map the bitmap specified by the arguments. | ||||
*/ | */ | ||||
kd->pt_map = _kvm_malloc(kd, map_len); | kd->pt_map = _kvm_malloc(kd, map_len); | ||||
if (kd->pt_map == NULL) { | if (kd->pt_map == NULL) { | ||||
_kvm_err(kd, kd->program, "cannot allocate %zu bytes for bitmap", | _kvm_err(kd, kd->program, "cannot allocate %zu bytes for bitmap", | ||||
map_len); | map_len); | ||||
Show All 39 Lines | _kvm_pt_init(kvm_t *kd, size_t dump_avail_size, off_t dump_avail_off, | ||||
} | } | ||||
assert(pc_bins * sizeof(*popcount_bin) == | assert(pc_bins * sizeof(*popcount_bin) == | ||||
((uintptr_t)popcount_bin - (uintptr_t)kd->pt_popcounts)); | ((uintptr_t)popcount_bin - (uintptr_t)kd->pt_popcounts)); | ||||
kd->pt_sparse_off = sparse_off; | kd->pt_sparse_off = sparse_off; | ||||
kd->pt_sparse_size = (uint64_t)*popcount_bin * page_size; | kd->pt_sparse_size = (uint64_t)*popcount_bin * page_size; | ||||
kd->pt_page_size = page_size; | kd->pt_page_size = page_size; | ||||
kd->pt_word_size = word_size; | |||||
/* | /* | ||||
* Map the sparse page array. This is useful for performing point | * Map the sparse page array. This is useful for performing point | ||||
* lookups of specific pages, e.g. for kvm_walk_pages. Generally, | * lookups of specific pages, e.g. for kvm_walk_pages. Generally, | ||||
* this is much larger than is reasonable to read in up front, so | * this is much larger than is reasonable to read in up front, so | ||||
* mmap it in instead. | * mmap it in instead. | ||||
*/ | */ | ||||
kd->sparse_map = mmap(NULL, kd->pt_sparse_size, PROT_READ, | kd->sparse_map = mmap(NULL, kd->pt_sparse_size, PROT_READ, | ||||
Show All 27 Lines | if (pread(kd->pmfd, kd->page_map, pmap_size, pmap_off) != exp_len) { | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static inline uint64_t | static inline uint64_t | ||||
dump_avail_n(kvm_t *kd, long i) | dump_avail_n(kvm_t *kd, long i) | ||||
{ | { | ||||
uint32_t *d32; | |||||
if (kd->pt_word_size == sizeof(uint32_t)) { | |||||
d32 = (uint32_t *)kd->dump_avail; | |||||
return (_kvm32toh(kd, d32[i])); | |||||
} else | |||||
return (_kvm64toh(kd, kd->dump_avail[i])); | return (_kvm64toh(kd, kd->dump_avail[i])); | ||||
} | } | ||||
uint64_t | uint64_t | ||||
_kvm_pa_bit_id(kvm_t *kd, uint64_t pa, unsigned int page_size) | _kvm_pa_bit_id(kvm_t *kd, uint64_t pa, unsigned int page_size) | ||||
{ | { | ||||
uint64_t adj; | uint64_t adj; | ||||
long i; | long i; | ||||
▲ Show 20 Lines • Show All 405 Lines • Show Last 20 Lines |