#include <libkern/OSDebug.h>
typedef struct {
- queue_chain_t chain;
+ queue_chain_t chain;
- pmap_t pmap;
- vm_offset_t start;
- vm_offset_t end;
+ pmap_t pmap;
+ vm_offset_t start;
+ vm_offset_t end;
} probe_t;
#if CONFIG_PGTRACE_NONKEXT
typedef uint8_t RWLOCK;
typedef struct {
- uint64_t id;
- pgtrace_run_result_t res;
- void *stack[PGTRACE_STACK_DEPTH];
+ uint64_t id;
+ pgtrace_run_result_t res;
+ void *stack[PGTRACE_STACK_DEPTH];
} log_t;
//--------------------------------------------
// Statics
//
static struct {
- log_t *logs; // Protect
- uint32_t size; // Protect
- uint64_t rdidx, wridx; // Protect
- decl_simple_lock_data(, loglock);
-
- uint64_t id;
- uint32_t option;
- uint32_t enabled;
- uint32_t bytes;
-
- queue_head_t probes; // Protect
-
- lck_grp_t *lock_grp;
- lck_grp_attr_t *lock_grp_attr;
- lck_attr_t *lock_attr;
- lck_mtx_t probelock;
+ log_t *logs; // Protect
+ uint32_t size; // Protect
+ uint64_t rdidx, wridx; // Protect
+ decl_simple_lock_data(, loglock);
+
+ uint64_t id;
+ uint32_t option;
+ uint32_t enabled;
+ uint32_t bytes;
+
+ queue_head_t probes; // Protect
+
+ lck_grp_t *lock_grp;
+ lck_grp_attr_t *lock_grp_attr;
+ lck_attr_t *lock_attr;
+ lck_mtx_t probelock;
} pgtrace = {};
//--------------------------------------------
// Globals
//
-void pgtrace_init(void)
+void
+pgtrace_init(void)
{
- simple_lock_init(&pgtrace.loglock, 0);
+ simple_lock_init(&pgtrace.loglock, 0);
- pgtrace.lock_attr = lck_attr_alloc_init();
- pgtrace.lock_grp_attr = lck_grp_attr_alloc_init();
- pgtrace.lock_grp = lck_grp_alloc_init("pgtrace_lock", pgtrace.lock_grp_attr);
+ pgtrace.lock_attr = lck_attr_alloc_init();
+ pgtrace.lock_grp_attr = lck_grp_attr_alloc_init();
+ pgtrace.lock_grp = lck_grp_alloc_init("pgtrace_lock", pgtrace.lock_grp_attr);
- lck_mtx_init(&pgtrace.probelock, pgtrace.lock_grp, pgtrace.lock_attr);
+ lck_mtx_init(&pgtrace.probelock, pgtrace.lock_grp, pgtrace.lock_attr);
- queue_init(&pgtrace.probes);
+ queue_init(&pgtrace.probes);
- pgtrace.size = RBUF_DEFAULT_SIZE;
- pgtrace.logs = kalloc(RBUF_DEFAULT_SIZE * sizeof(log_t));
+ pgtrace.size = RBUF_DEFAULT_SIZE;
+ pgtrace.logs = kalloc(RBUF_DEFAULT_SIZE * sizeof(log_t));
}
-
-void pgtrace_clear_probe(void)
+
+void
+pgtrace_clear_probe(void)
{
- probe_t *p, *next;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p, *next;
+ queue_head_t *q = &pgtrace.probes;
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- p = (probe_t *)queue_first(q);
- while (!queue_end(q, (queue_entry_t)p)) {
- next = (probe_t *)queue_next(&(p->chain));
+ p = (probe_t *)queue_first(q);
+ while (!queue_end(q, (queue_entry_t)p)) {
+ next = (probe_t *)queue_next(&(p->chain));
- queue_remove(q, p, probe_t *, chain);
- kfree(p, sizeof(probe_t));
+ queue_remove(q, p, probe_t *, chain);
+ kfree(p, sizeof(probe_t));
- p = next;
- }
+ p = next;
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- return;
+ return;
}
-int pgtrace_add_probe(thread_t thread, vm_offset_t start, vm_offset_t end)
+int
+pgtrace_add_probe(thread_t thread, vm_offset_t start, vm_offset_t end)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
-
- if (start > end) {
- kprintf("%s Invalid start=%lx end=%lx\n", __func__, start, end);
- return -1;
- }
-
- p = kalloc(sizeof(probe_t));
- p->start = start;
- p->end = end;
- if (thread == NULL) {
- p->pmap = NULL;
- } else {
- p->pmap = vm_map_pmap(thread->map);
- }
-
- lck_mtx_lock(&pgtrace.probelock);
- queue_enter(q, p, probe_t *, chain);
- lck_mtx_unlock(&pgtrace.probelock);
-
- return 0;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
+
+ if (start > end) {
+ kprintf("%s Invalid start=%lx end=%lx\n", __func__, start, end);
+ return -1;
+ }
+
+ p = kalloc(sizeof(probe_t));
+ p->start = start;
+ p->end = end;
+ if (thread == NULL) {
+ p->pmap = NULL;
+ } else {
+ p->pmap = vm_map_pmap(thread->map);
+ }
+
+ lck_mtx_lock(&pgtrace.probelock);
+ queue_enter(q, p, probe_t *, chain);
+ lck_mtx_unlock(&pgtrace.probelock);
+
+ return 0;
}
-void pgtrace_start(void)
+void
+pgtrace_start(void)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
- kprintf("%s\n", __func__);
+ kprintf("%s\n", __func__);
- if (pgtrace.enabled) {
- return;
- }
+ if (pgtrace.enabled) {
+ return;
+ }
- pgtrace.enabled = 1;
+ pgtrace.enabled = 1;
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- queue_iterate(q, p, probe_t *, chain) {
- pmap_pgtrace_add_page(p->pmap, p->start, p->end);
- }
+ queue_iterate(q, p, probe_t *, chain) {
+ pmap_pgtrace_add_page(p->pmap, p->start, p->end);
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- return;
+ return;
}
-void pgtrace_stop(void)
+void
+pgtrace_stop(void)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
- kprintf("%s\n", __func__);
+ kprintf("%s\n", __func__);
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- queue_iterate(q, p, probe_t *, chain) {
- pmap_pgtrace_delete_page(p->pmap, p->start, p->end);
- }
+ queue_iterate(q, p, probe_t *, chain) {
+ pmap_pgtrace_delete_page(p->pmap, p->start, p->end);
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- pgtrace.enabled = 0;
+ pgtrace.enabled = 0;
}
-uint32_t pgtrace_get_size(void)
+uint32_t
+pgtrace_get_size(void)
{
- return pgtrace.size;
+ return pgtrace.size;
}
-bool pgtrace_set_size(uint32_t size)
+bool
+pgtrace_set_size(uint32_t size)
{
- log_t *old_buf, *new_buf;
- uint32_t old_size, new_size = 1;
-
- // round up to next power of 2
- while (size > new_size) {
- new_size <<= 1;
- if (new_size > 0x100000) {
- // over million entries
- kprintf("%s: size=%x new_size=%x is too big\n", __func__, size, new_size);
- return false;
- }
- }
-
- new_buf = kalloc(new_size * sizeof(log_t));
- if (new_buf == NULL) {
- kprintf("%s: can't allocate new_size=%x\n entries", __func__, new_size);
- return false;
- }
-
- pgtrace_stop();
-
- simple_lock(&pgtrace.loglock);
- old_buf = pgtrace.logs;
- old_size = pgtrace.size;
- pgtrace.logs = new_buf;
- pgtrace.size = new_size;
- pgtrace.rdidx = pgtrace.wridx = 0;
- simple_unlock(&pgtrace.loglock);
-
- if (old_buf) {
- kfree(old_buf, old_size * sizeof(log_t));
- }
-
- return true;
+ log_t *old_buf, *new_buf;
+ uint32_t old_size, new_size = 1;
+
+ // round up to next power of 2
+ while (size > new_size) {
+ new_size <<= 1;
+ if (new_size > 0x100000) {
+ // over million entries
+ kprintf("%s: size=%x new_size=%x is too big\n", __func__, size, new_size);
+ return false;
+ }
+ }
+
+ new_buf = kalloc(new_size * sizeof(log_t));
+ if (new_buf == NULL) {
+ kprintf("%s: can't allocate new_size=%x\n entries", __func__, new_size);
+ return false;
+ }
+
+ pgtrace_stop();
+
+ simple_lock(&pgtrace.loglock);
+ old_buf = pgtrace.logs;
+ old_size = pgtrace.size;
+ pgtrace.logs = new_buf;
+ pgtrace.size = new_size;
+ pgtrace.rdidx = pgtrace.wridx = 0;
+ simple_unlock(&pgtrace.loglock);
+
+ if (old_buf) {
+ kfree(old_buf, old_size * sizeof(log_t));
+ }
+
+ return true;
}
-void pgtrace_clear_trace(void)
+void
+pgtrace_clear_trace(void)
{
- simple_lock(&pgtrace.loglock);
- pgtrace.rdidx = pgtrace.wridx = 0;
- simple_unlock(&pgtrace.loglock);
+ simple_lock(&pgtrace.loglock);
+ pgtrace.rdidx = pgtrace.wridx = 0;
+ simple_unlock(&pgtrace.loglock);
}
-boolean_t pgtrace_active(void)
+boolean_t
+pgtrace_active(void)
{
- return (pgtrace.enabled > 0);
+ return pgtrace.enabled > 0;
}
-uint32_t pgtrace_get_option(void)
+uint32_t
+pgtrace_get_option(void)
{
- return pgtrace.option;
+ return pgtrace.option;
}
-void pgtrace_set_option(uint32_t option)
+void
+pgtrace_set_option(uint32_t option)
{
- pgtrace.option = option;
+ pgtrace.option = option;
}
// pgtrace_write_log() is in interrupt disabled context
-void pgtrace_write_log(pgtrace_run_result_t res)
+void
+pgtrace_write_log(pgtrace_run_result_t res)
{
- uint8_t i;
- log_t log = {};
- const char *rwmap[] = { "R", "W", "PREFETCH" };
+ uint8_t i;
+ log_t log = {};
+ const char *rwmap[] = { "R", "W", "PREFETCH" };
+
+ log.id = pgtrace.id++;
+ log.res = res;
- log.id = pgtrace.id++;
- log.res = res;
+ if (pgtrace.option & PGTRACE_OPTION_KPRINTF) {
+ char msg[MSG_MAX];
+ char *p;
- if (pgtrace.option & PGTRACE_OPTION_KPRINTF) {
- char msg[MSG_MAX];
- char *p;
+ p = msg;
- p = msg;
+ snprintf(p, MSG_MAX, "%llu %s ", res.rr_time, rwmap[res.rr_rw]);
+ p += strlen(p);
- snprintf(p, MSG_MAX, "%llu %s ", res.rr_time, rwmap[res.rr_rw]);
- p += strlen(p);
+ for (i = 0; i < res.rr_num; i++) {
+ snprintf(p, MSG_MAX - (p - msg), "%lx=%llx ", res.rr_addrdata[i].ad_addr, res.rr_addrdata[i].ad_data);
+ p += strlen(p);
+ }
- for (i = 0; i < res.rr_num; i++) {
- snprintf(p, MSG_MAX-(p-msg), "%lx=%llx ", res.rr_addrdata[i].ad_addr, res.rr_addrdata[i].ad_data);
- p += strlen(p);
- }
+ kprintf("%s %s\n", __func__, msg);
+ }
- kprintf("%s %s\n", __func__, msg);
- }
-
- if (pgtrace.option & PGTRACE_OPTION_STACK) {
- OSBacktrace(log.stack, PGTRACE_STACK_DEPTH);
- }
+ if (pgtrace.option & PGTRACE_OPTION_STACK) {
+ OSBacktrace(log.stack, PGTRACE_STACK_DEPTH);
+ }
- pgtrace.bytes += sizeof(log);
+ pgtrace.bytes += sizeof(log);
- simple_lock(&pgtrace.loglock);
+ simple_lock(&pgtrace.loglock);
- pgtrace.logs[RBUF_IDX(pgtrace.wridx, pgtrace.size-1)] = log;
+ pgtrace.logs[RBUF_IDX(pgtrace.wridx, pgtrace.size - 1)] = log;
- // Advance rdidx if ring is full
- if (RBUF_IDX(pgtrace.wridx, pgtrace.size-1) == RBUF_IDX(pgtrace.rdidx, pgtrace.size-1) &&
- (pgtrace.wridx != pgtrace.rdidx)) {
- pgtrace.rdidx++;
- }
- pgtrace.wridx++;
+ // Advance rdidx if ring is full
+ if (RBUF_IDX(pgtrace.wridx, pgtrace.size - 1) == RBUF_IDX(pgtrace.rdidx, pgtrace.size - 1) &&
+ (pgtrace.wridx != pgtrace.rdidx)) {
+ pgtrace.rdidx++;
+ }
+ pgtrace.wridx++;
- // Signal if ring was empty
- if (pgtrace.wridx == (pgtrace.rdidx + 1)) {
- thread_wakeup(pgtrace.logs);
- }
+ // Signal if ring was empty
+ if (pgtrace.wridx == (pgtrace.rdidx + 1)) {
+ thread_wakeup(pgtrace.logs);
+ }
- simple_unlock(&pgtrace.loglock);
+ simple_unlock(&pgtrace.loglock);
- return;
+ return;
}
// pgtrace_read_log() is in user thread
-int64_t pgtrace_read_log(uint8_t *buf, uint32_t size)
+int64_t
+pgtrace_read_log(uint8_t *buf, uint32_t size)
{
- int total, front, back;
- boolean_t ints;
- wait_result_t wr;
+ int total, front, back;
+ boolean_t ints;
+ wait_result_t wr;
- if (pgtrace.enabled == FALSE) {
- return -EINVAL;
- }
+ if (pgtrace.enabled == FALSE) {
+ return -EINVAL;
+ }
- total = size / sizeof(log_t);
+ total = size / sizeof(log_t);
- // Check if buf is too small
- if (buf && total == 0) {
- return -EINVAL;
- }
+ // Check if buf is too small
+ if (buf && total == 0) {
+ return -EINVAL;
+ }
- ints = ml_set_interrupts_enabled(FALSE);
- simple_lock(&pgtrace.loglock);
+ ints = ml_set_interrupts_enabled(FALSE);
+ simple_lock(&pgtrace.loglock);
- // Wait if ring is empty
- if (pgtrace.rdidx == pgtrace.wridx) {
- assert_wait(pgtrace.logs, THREAD_ABORTSAFE);
+ // Wait if ring is empty
+ if (pgtrace.rdidx == pgtrace.wridx) {
+ assert_wait(pgtrace.logs, THREAD_ABORTSAFE);
- simple_unlock(&pgtrace.loglock);
- ml_set_interrupts_enabled(ints);
+ simple_unlock(&pgtrace.loglock);
+ ml_set_interrupts_enabled(ints);
- wr = thread_block(NULL);
- if (wr != THREAD_AWAKENED) {
- return -EINTR;
- }
+ wr = thread_block(NULL);
+ if (wr != THREAD_AWAKENED) {
+ return -EINTR;
+ }
- ints = ml_set_interrupts_enabled(FALSE);
- simple_lock(&pgtrace.loglock);
- }
+ ints = ml_set_interrupts_enabled(FALSE);
+ simple_lock(&pgtrace.loglock);
+ }
- // Trim the size
- if ((pgtrace.rdidx + total) > pgtrace.wridx) {
- total = (int)(pgtrace.wridx - pgtrace.rdidx);
- }
+ // Trim the size
+ if ((pgtrace.rdidx + total) > pgtrace.wridx) {
+ total = (int)(pgtrace.wridx - pgtrace.rdidx);
+ }
- // Copy front
- if ((RBUF_IDX(pgtrace.rdidx, pgtrace.size-1) + total) >= pgtrace.size) {
- front = pgtrace.size - RBUF_IDX(pgtrace.rdidx, pgtrace.size-1);
- } else {
- front = total;
- }
+ // Copy front
+ if ((RBUF_IDX(pgtrace.rdidx, pgtrace.size - 1) + total) >= pgtrace.size) {
+ front = pgtrace.size - RBUF_IDX(pgtrace.rdidx, pgtrace.size - 1);
+ } else {
+ front = total;
+ }
- memcpy(buf, &(pgtrace.logs[RBUF_IDX(pgtrace.rdidx, pgtrace.size-1)]), front*sizeof(log_t));
+ memcpy(buf, &(pgtrace.logs[RBUF_IDX(pgtrace.rdidx, pgtrace.size - 1)]), front * sizeof(log_t));
- // Copy back if any
- back = total-front;
- if (back) {
- buf += front * sizeof(log_t);
- memcpy(buf, pgtrace.logs, back*sizeof(log_t));
- }
+ // Copy back if any
+ back = total - front;
+ if (back) {
+ buf += front * sizeof(log_t);
+ memcpy(buf, pgtrace.logs, back * sizeof(log_t));
+ }
- pgtrace.rdidx += total;
+ pgtrace.rdidx += total;
- simple_unlock(&pgtrace.loglock);
- ml_set_interrupts_enabled(ints);
+ simple_unlock(&pgtrace.loglock);
+ ml_set_interrupts_enabled(ints);
- return total*sizeof(log_t);
+ return total * sizeof(log_t);
}
-int pgtrace_get_stats(pgtrace_stats_t *stats)
+int
+pgtrace_get_stats(pgtrace_stats_t *stats)
{
- if (!stats) {
- return -1;
- }
+ if (!stats) {
+ return -1;
+ }
- stats->stat_logger.sl_bytes = pgtrace.bytes;
- pgtrace_decoder_get_stats(stats);
+ stats->stat_logger.sl_bytes = pgtrace.bytes;
+ pgtrace_decoder_get_stats(stats);
- return 0;
+ return 0;
}
#else // CONFIG_PGTRACE_NONKEXT
static struct {
- bool active;
- decoder_t *decoder;
- logger_t *logger;
- queue_head_t probes;
-
- lck_grp_t *lock_grp;
- lck_grp_attr_t *lock_grp_attr;
- lck_attr_t *lock_attr;
- lck_mtx_t probelock;
+ bool active;
+ decoder_t *decoder;
+ logger_t *logger;
+ queue_head_t probes;
+
+ lck_grp_t *lock_grp;
+ lck_grp_attr_t *lock_grp_attr;
+ lck_attr_t *lock_attr;
+ lck_mtx_t probelock;
} pgtrace = {};
//------------------------------------
// - pgtrace_decode_and_run
// - pgtrace_write_log
//------------------------------------
-int pgtrace_decode_and_run(uint32_t inst, vm_offset_t fva, vm_map_offset_t *cva_page, arm_saved_state_t *ss, pgtrace_run_result_t *res)
+int
+pgtrace_decode_and_run(uint32_t inst, vm_offset_t fva, vm_map_offset_t *cva_page, arm_saved_state_t *ss, pgtrace_run_result_t *res)
{
- vm_offset_t pa, cva;
- pgtrace_instruction_info_t info;
- vm_offset_t cva_front_page = cva_page[0];
- vm_offset_t cva_cur_page = cva_page[1];
-
- pgtrace.decoder->decode(inst, ss, &info);
-
- if (info.addr == fva) {
- cva = cva_cur_page + (fva & ARM_PGMASK);
- } else {
- // which means a front page is not a tracing page
- cva = cva_front_page + (fva & ARM_PGMASK);
- }
-
- pa = mmu_kvtop(cva);
- if (!pa) {
- panic("%s: invalid address cva=%lx fva=%lx info.addr=%lx inst=%x", __func__, cva, fva, info.addr, inst);
- }
-
- absolutetime_to_nanoseconds(mach_absolute_time(), &res->rr_time);
-
- pgtrace.decoder->run(inst, pa, cva, ss, res);
-
- return 0;
+ vm_offset_t pa, cva;
+ pgtrace_instruction_info_t info;
+ vm_offset_t cva_front_page = cva_page[0];
+ vm_offset_t cva_cur_page = cva_page[1];
+
+ pgtrace.decoder->decode(inst, ss, &info);
+
+ if (info.addr == fva) {
+ cva = cva_cur_page + (fva & ARM_PGMASK);
+ } else {
+ // which means a front page is not a tracing page
+ cva = cva_front_page + (fva & ARM_PGMASK);
+ }
+
+ pa = mmu_kvtop(cva);
+ if (!pa) {
+ panic("%s: invalid address cva=%lx fva=%lx info.addr=%lx inst=%x", __func__, cva, fva, info.addr, inst);
+ }
+
+ absolutetime_to_nanoseconds(mach_absolute_time(), &res->rr_time);
+
+ pgtrace.decoder->run(inst, pa, cva, ss, res);
+
+ return 0;
}
-int pgtrace_write_log(pgtrace_run_result_t res)
+int
+pgtrace_write_log(pgtrace_run_result_t res)
{
- pgtrace.logger->write(res);
- return 0;
+ pgtrace.logger->write(res);
+ return 0;
}
//------------------------------------
// - pgtrace_stop
// - pgtrace_active
//------------------------------------
-int pgtrace_init(decoder_t *decoder, logger_t *logger)
+int
+pgtrace_init(decoder_t *decoder, logger_t *logger)
{
- kprintf("%s decoder=%p logger=%p\n", __func__, decoder, logger);
+ kprintf("%s decoder=%p logger=%p\n", __func__, decoder, logger);
- assert(decoder && logger);
+ assert(decoder && logger);
- if (decoder->magic != 0xfeedface || logger->magic != 0xfeedface ||
- strcmp(decoder->arch, "arm64") != 0 || strcmp(logger->arch, "arm64") != 0) {
- kprintf("%s:wrong decoder/logger magic=%llx/%llx arch=%s/%s", __func__, decoder->magic, logger->magic, decoder->arch, logger->arch);
- return EINVAL;
- }
+ if (decoder->magic != 0xfeedface || logger->magic != 0xfeedface ||
+ strcmp(decoder->arch, "arm64") != 0 || strcmp(logger->arch, "arm64") != 0) {
+ kprintf("%s:wrong decoder/logger magic=%llx/%llx arch=%s/%s", __func__, decoder->magic, logger->magic, decoder->arch, logger->arch);
+ return EINVAL;
+ }
- pgtrace.lock_attr = lck_attr_alloc_init();
- pgtrace.lock_grp_attr = lck_grp_attr_alloc_init();
- pgtrace.lock_grp = lck_grp_alloc_init("pgtrace_lock", pgtrace.lock_grp_attr);
+ pgtrace.lock_attr = lck_attr_alloc_init();
+ pgtrace.lock_grp_attr = lck_grp_attr_alloc_init();
+ pgtrace.lock_grp = lck_grp_alloc_init("pgtrace_lock", pgtrace.lock_grp_attr);
- lck_mtx_init(&pgtrace.probelock, pgtrace.lock_grp, pgtrace.lock_attr);
+ lck_mtx_init(&pgtrace.probelock, pgtrace.lock_grp, pgtrace.lock_attr);
- queue_init(&pgtrace.probes);
- pgtrace.decoder = decoder;
- pgtrace.logger = logger;
+ queue_init(&pgtrace.probes);
+ pgtrace.decoder = decoder;
+ pgtrace.logger = logger;
- return 0;
+ return 0;
}
-
-int pgtrace_add_probe(thread_t thread, vm_offset_t start, vm_offset_t end)
+
+int
+pgtrace_add_probe(thread_t thread, vm_offset_t start, vm_offset_t end)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
-
- kprintf("%s start=%lx end=%lx\n", __func__, start, end);
-
- if (start > end) {
- kprintf("%s Invalid start=%lx end=%lx\n", __func__, start, end);
- return -1;
- }
-
- p = kalloc(sizeof(probe_t));
- p->start = start;
- p->end = end;
- if (thread == NULL) {
- p->pmap = NULL;
- } else {
- p->pmap = vm_map_pmap(thread->map);
- }
-
- lck_mtx_lock(&pgtrace.probelock);
- queue_enter(q, p, probe_t *, chain);
- lck_mtx_unlock(&pgtrace.probelock);
-
- return 0;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
+
+ kprintf("%s start=%lx end=%lx\n", __func__, start, end);
+
+ if (start > end) {
+ kprintf("%s Invalid start=%lx end=%lx\n", __func__, start, end);
+ return -1;
+ }
+
+ p = kalloc(sizeof(probe_t));
+ p->start = start;
+ p->end = end;
+ if (thread == NULL) {
+ p->pmap = NULL;
+ } else {
+ p->pmap = vm_map_pmap(thread->map);
+ }
+
+ lck_mtx_lock(&pgtrace.probelock);
+ queue_enter(q, p, probe_t *, chain);
+ lck_mtx_unlock(&pgtrace.probelock);
+
+ return 0;
}
-void pgtrace_clear_probe(void)
+void
+pgtrace_clear_probe(void)
{
- probe_t *p, *next;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p, *next;
+ queue_head_t *q = &pgtrace.probes;
- kprintf("%s\n", __func__);
+ kprintf("%s\n", __func__);
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- p = (probe_t *)queue_first(q);
- while (!queue_end(q, (queue_entry_t)p)) {
- next = (probe_t *)queue_next(&(p->chain));
+ p = (probe_t *)queue_first(q);
+ while (!queue_end(q, (queue_entry_t)p)) {
+ next = (probe_t *)queue_next(&(p->chain));
- queue_remove(q, p, probe_t *, chain);
- kfree(p, sizeof(probe_t));
+ queue_remove(q, p, probe_t *, chain);
+ kfree(p, sizeof(probe_t));
- p = next;
- }
+ p = next;
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- return;
+ return;
}
-void pgtrace_start(void)
+void
+pgtrace_start(void)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
- kprintf("%s\n", __func__);
+ kprintf("%s\n", __func__);
- if (pgtrace.active == true) {
- return;
- }
+ if (pgtrace.active == true) {
+ return;
+ }
- pgtrace.active = true;
+ pgtrace.active = true;
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- queue_iterate(q, p, probe_t *, chain) {
- pmap_pgtrace_add_page(p->pmap, p->start, p->end);
- }
+ queue_iterate(q, p, probe_t *, chain) {
+ pmap_pgtrace_add_page(p->pmap, p->start, p->end);
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- return;
+ return;
}
-void pgtrace_stop(void)
+void
+pgtrace_stop(void)
{
- probe_t *p;
- queue_head_t *q = &pgtrace.probes;
+ probe_t *p;
+ queue_head_t *q = &pgtrace.probes;
- kprintf("%s\n", __func__);
+ kprintf("%s\n", __func__);
- lck_mtx_lock(&pgtrace.probelock);
+ lck_mtx_lock(&pgtrace.probelock);
- queue_iterate(q, p, probe_t *, chain) {
- pmap_pgtrace_delete_page(p->pmap, p->start, p->end);
- }
+ queue_iterate(q, p, probe_t *, chain) {
+ pmap_pgtrace_delete_page(p->pmap, p->start, p->end);
+ }
- lck_mtx_unlock(&pgtrace.probelock);
+ lck_mtx_unlock(&pgtrace.probelock);
- pgtrace.active = false;
+ pgtrace.active = false;
}
-bool pgtrace_active(void)
+bool
+pgtrace_active(void)
{
- return pgtrace.active;
+ return pgtrace.active;
}
#endif // CONFIG_PGTRACE_NONKEXT
#else
extern void pgtrace_add_probe(void);
extern void pgtrace_init(void);
extern void pgtrace_active(void);
-void pgtrace_stop(void) {}
-void pgtrace_start(void) {}
-void pgtrace_clear_probe(void) {}
-void pgtrace_add_probe(void) {}
-void pgtrace_init(void) {}
-void pgtrace_active(void) {}
+void
+pgtrace_stop(void)
+{
+}
+void
+pgtrace_start(void)
+{
+}
+void
+pgtrace_clear_probe(void)
+{
+}
+void
+pgtrace_add_probe(void)
+{
+}
+void
+pgtrace_init(void)
+{
+}
+void
+pgtrace_active(void)
+{
+}
#endif