static void handle_nvrm_ioctl_vspace_unmap(uint32_t fd, struct nvrm_ioctl_vspace_unmap *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); struct gpu_object *obj = gpu_object_find(s->cid, s->handle); if (!obj) { mmt_error("nvrm_ioctl_vspace_unmap: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } struct gpu_mapping *gpu_mapping; for (gpu_mapping = obj->gpu_mappings; gpu_mapping != NULL; gpu_mapping = gpu_mapping->next) if (gpu_mapping->address == s->addr) { gpu_mapping->address = 0; gpu_mapping_destroy(gpu_mapping); return; } mmt_error("can't find matching gpu_mappings%s\n", ""); demmt_abort(); }
static void handle_nvrm_ioctl_host_unmap(uint32_t fd, struct nvrm_ioctl_host_unmap *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); struct gpu_object *obj = gpu_object_find(s->cid, s->handle); if (!obj) { mmt_error("nvrm_ioctl_host_unmap: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } struct cpu_mapping *cpu_mapping; for (cpu_mapping = obj->cpu_mappings; cpu_mapping != NULL; cpu_mapping = cpu_mapping->next) if (cpu_mapping->mmap_offset == (s->foffset & ~0xfffUL)) { cpu_mapping->mmap_offset = 0; disconnect_cpu_mapping_from_gpu_object(cpu_mapping); return; } // weird, host_unmap accepts cpu addresses in foffset field for (cpu_mapping = obj->cpu_mappings; cpu_mapping != NULL; cpu_mapping = cpu_mapping->next) if (cpu_mapping->cpu_addr == (s->foffset & ~0xfffUL)) { //mmt_error("host_unmap with cpu address as offset, wtf?%s\n", ""); cpu_mapping->mmap_offset = 0; disconnect_cpu_mapping_from_gpu_object(cpu_mapping); return; } mmt_error("can't find matching mapping%s\n", ""); demmt_abort(); }
static void demmt_memread(struct mmt_read *w, void *state) { char comment[50]; struct cpu_mapping *mapping = get_cpu_mapping(w->id); if (mapping == NULL) { mmt_error("invalid buffer id: %d\n", w->id); demmt_abort(); } uint64_t gpu_addr = cpu_mapping_to_gpu_addr(mapping, w->offset); if (print_gpu_addresses && gpu_addr) sprintf(comment, " (gpu=0x%08" PRIx64 ")", gpu_addr); else comment[0] = 0; if (dump_memory_reads) { unsigned char *data = &w->data[0]; if (w->len == 1) mmt_printf("r %d:0x%04x%s, 0x%02x\n", w->id, w->offset, comment, data[0]); else if (w->len == 2) mmt_printf("r %d:0x%04x%s, 0x%04x\n", w->id, w->offset, comment, *(uint16_t *)&data[0]); else if (w->len == 4 || w->len == 8 || w->len == 16 || w->len == 32) { mmt_printf("r %d:0x%04x%s, ", w->id, w->offset, comment); int i; for (i = 0; i < w->len; i += 4) mmt_printf("0x%08x ", *(uint32_t *)&data[i]); mmt_printf("%s\n", ""); } else { mmt_error("unhandled size: %d\n", w->len); demmt_abort(); } } }
int nvrm_get_chipset(struct gpu_object *obj) { struct gpu_object *dev = nvrm_get_device(obj); if (dev && dev->class_data) return nvrm_dev(dev)->chipset; if (chipset) return chipset; mmt_error("Can't detect chipset, you need to use -m option or regenerate trace with newer mmt (> Sep 7 2014)%s\n", ""); demmt_abort(); }
static void demmt_mremap(struct mmt_mremap *mm, void *state) { if (get_cpu_mapping(mm->id) == NULL) { mmt_error("invalid buffer id: %d\n", mm->id); demmt_abort(); } if (dump_sys_mremap) mmt_log("mremap: old_address: 0x%" PRIx64 ", new_address: 0x%" PRIx64 ", old_length: 0x%08" PRIx64 ", new_length: 0x%08" PRIx64 ", id: %d, offset: 0x%08" PRIx64 "\n", mm->old_start, mm->start, mm->old_len, mm->len, mm->id, mm->offset); buffer_mremap(mm); }
static void demmt_munmap(struct mmt_unmap *mm, void *state) { if (get_cpu_mapping(mm->id) == NULL) { mmt_error("invalid buffer id: %d\n", mm->id); demmt_abort(); } if (dump_sys_munmap) mmt_log("munmap: address: 0x%" PRIx64 ", length: 0x%08" PRIx64 ", id: %d, offset: 0x%08" PRIx64 "", mm->start, mm->len, mm->id, mm->offset); nvrm_munmap(mm->id, mm->start, mm->len, mm->offset); }
void demmt_memwrite2(struct mmt_write2 *w2, void *state) { uint32_t i; struct cpu_mapping *m = NULL; for (i = 0; i < max_id + 1; ++i) { m = get_cpu_mapping(i); if (m && w2->addr >= m->cpu_addr && w2->addr < m->cpu_addr + m->length) break; } if (i != max_id + 1) { if (!mem2_buffer) mem2_buffer = malloc(4096); struct mmt_write *w1 = mem2_buffer; w1->msg_type = w2->msg_type; w1->id = i; w1->offset = w2->addr - m->cpu_addr; w1->len = w2->len; memcpy(w1->data, w2->data, w1->len); demmt_memwrite(w1, state); } if (dump_memory_writes) { unsigned char *data = &w2->data[0]; if (w2->len == 1) mmt_printf("@w 0x%" PRIx64 ", 0x%02x\n", w2->addr, data[0]); else if (w2->len == 2) mmt_printf("@w 0x%" PRIx64 ", 0x%04x\n", w2->addr, *(uint16_t *)&data[0]); else if (w2->len == 4 || w2->len == 8 || w2->len == 16 || w2->len == 32) { mmt_printf("@w 0x%" PRIx64 ", ", w2->addr); int i; for (i = 0; i < w2->len; i += 4) mmt_printf("0x%08x ", *(uint32_t *)&data[i]); mmt_printf("%s\n", ""); } else { mmt_error("unhandled size: %d\n", w2->len); demmt_abort(); } } }
static void handle_nvrm_ioctl_host_unmap(uint32_t fd, struct nvrm_ioctl_host_unmap *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); struct gpu_object *obj = gpu_object_find(s->cid, s->handle); if (!obj) { mmt_error("nvrm_ioctl_host_unmap: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } struct cpu_mapping *cpu_mapping; /* it seems, depending on blob version, foffset have different meaning :/ */ for (cpu_mapping = obj->cpu_mappings; cpu_mapping != NULL; cpu_mapping = cpu_mapping->next) if (cpu_mapping->map_id == s->foffset) { cpu_mapping->mmap_offset = -1; cpu_mapping->map_id = -1; disconnect_cpu_mapping_from_gpu_object(cpu_mapping); return; } for (cpu_mapping = obj->cpu_mappings; cpu_mapping != NULL; cpu_mapping = cpu_mapping->next) if (cpu_mapping->mmap_offset == (s->foffset & ~0xfffUL)) { cpu_mapping->mmap_offset = -1; cpu_mapping->map_id = -1; disconnect_cpu_mapping_from_gpu_object(cpu_mapping); return; } for (cpu_mapping = obj->cpu_mappings; cpu_mapping != NULL; cpu_mapping = cpu_mapping->next) if (cpu_mapping->cpu_addr == (s->foffset & ~0xfffUL)) { //mmt_error("host_unmap with cpu address as offset, wtf?%s\n", ""); cpu_mapping->mmap_offset = -1; cpu_mapping->map_id = -1; disconnect_cpu_mapping_from_gpu_object(cpu_mapping); return; } mmt_error("can't find matching mapping%s\n", ""); demmt_abort(); }
static void demmt_sync(struct mmt_sync *o, void *state) { if (mmt_sync_fd == -1) return; fflush(stdout); fdatasync(1); int cnt = 4; while (cnt) { int r = write(mmt_sync_fd, ((char *)&o->id) + 4 - cnt, cnt); if (r > 0) cnt -= r; else if (r != EINTR) demmt_abort(); } fdatasync(mmt_sync_fd); }
int main(int argc, char *argv[]) { char *filename = read_opts(argc, argv); /* set up an rnn context */ rnn_init(); rnndb = rnn_newdb(); rnn_parsefile(rnndb, "fifo/nv_objects.xml"); if (rnndb->estatus) demmt_abort(); rnn_prepdb(rnndb); domain = rnn_finddomain(rnndb, "SUBCHAN"); if (!domain) demmt_abort(); rnndb_g80_texture = rnn_newdb(); rnn_parsefile(rnndb_g80_texture, "graph/g80_texture.xml"); if (rnndb_g80_texture->estatus) demmt_abort(); rnn_parsefile(rnndb_g80_texture, "graph/gm107_texture.xml"); if (rnndb_g80_texture->estatus) demmt_abort(); rnn_prepdb(rnndb_g80_texture); rnndb_gf100_shaders = rnn_newdb(); rnn_parsefile(rnndb_gf100_shaders, "graph/gf100_shaders.xml"); if (rnndb_gf100_shaders->estatus) demmt_abort(); rnn_prepdb(rnndb_gf100_shaders); gf100_shaders_ctx = rnndec_newcontext(rnndb_gf100_shaders); gf100_shaders_ctx->colors = colors; /* doesn't matter which, just needs to exist to make it * possible to modify later. */ rnndec_varadd(gf100_shaders_ctx, "GF100_SHADER_KIND", "FP"); rnndb_nvrm_object = rnn_newdb(); rnn_parsefile(rnndb_nvrm_object, "../docs/nvrm/rnndb/nvrm_object.xml"); if (rnndb_nvrm_object->estatus) demmt_abort(); rnn_prepdb(rnndb_nvrm_object); tic_domain = rnn_finddomain(rnndb_g80_texture, "TIC"); tic2_domain = rnn_finddomain(rnndb_g80_texture, "TIC2"); tsc_domain = rnn_finddomain(rnndb_g80_texture, "TSC"); gf100_sp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_SP_HEADER"); gf100_fp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_FP_HEADER"); if (!gf100_sp_header_domain || !gf100_fp_header_domain) demmt_abort(); gk104_cp_header_domain = rnn_finddomain(rnndb, "GK104_COMPUTE_LAUNCH_DESC"); if (!gk104_cp_header_domain) demmt_abort(); if (filename) { close(0); if (open_input(filename) == NULL) { perror("open"); exit(1); } free(filename); } if (pager_enabled) { int pipe_fds[2]; pid_t pid; if (pipe(pipe_fds) < 0) { perror("pipe"); demmt_abort(); } pid = fork(); if (pid < 0) { perror("fork"); demmt_abort(); } if (pid > 0) { char *less_argv[] = { "less", "-ScR", NULL }; close(pipe_fds[1]); dup2(pipe_fds[0], 0); close(pipe_fds[0]); execvp(less_argv[0], less_argv); perror("exec"); demmt_abort(); } close(pipe_fds[0]); dup2(pipe_fds[1], 1); dup2(pipe_fds[1], 2); close(pipe_fds[1]); } #ifdef LIBSECCOMP_AVAILABLE if (seccomp_level) { int rc; scmp_filter_ctx ctx; if (seccomp_level == 2) ctx = seccomp_init(SCMP_ACT_KILL); else ctx = seccomp_init(SCMP_ACT_TRACE(1234)); if (!ctx) { fprintf(stderr, "seccomp_init failed\n"); exit(1); } rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, 0)); if (rc != 0) exit(1); seccomp_syscall_priority(ctx, SCMP_SYS(read), 254); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)); if (rc != 0) exit(1); seccomp_syscall_priority(ctx, SCMP_SYS(write), 255); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 1, SCMP_A0(SCMP_CMP_EQ, 1)); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 2, SCMP_A0(SCMP_CMP_EQ, 1), SCMP_A1(SCMP_CMP_EQ, 0x5401/*TCGETS*/)); if (rc != 0) exit(1); rc = seccomp_load(ctx); if (rc != 0) { fprintf(stderr, "seccomp_load failed with error: %d\n", rc); exit(1); } seccomp_release(ctx); } #endif mmt_decode(&demmt_funcs.base, NULL); fflush(stdout); fini_macrodis(); demmt_cleanup_isas(); rnndec_freecontext(gf100_shaders_ctx); rnn_freedb(rnndb); rnn_freedb(rnndb_g80_texture); rnn_freedb(rnndb_gf100_shaders); rnn_freedb(rnndb_nvrm_object); rnn_fini(); return 0; }
static inline struct nvrm_device *nvrm_dev(struct gpu_object *dev) { if (dev->class_ != NVRM_DEVICE_0) demmt_abort(); return dev->class_data; }