Beispiel #1
0
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();
}
Beispiel #2
0
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();
}
Beispiel #3
0
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();
		}
	}
}
Beispiel #4
0
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();
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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();
		}
	}
}
Beispiel #8
0
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();
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
}
Beispiel #11
0
static inline struct nvrm_device *nvrm_dev(struct gpu_object *dev)
{
	if (dev->class_ != NVRM_DEVICE_0)
		demmt_abort();
	return dev->class_data;
}