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_map(uint32_t fd, struct nvrm_ioctl_host_map *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_map: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } // NOTE: s->subdev may not be object's parent and may not even be an ancestor of its parent /* if (obj->parent != s->subdev) { struct gpu_object *subdev = find_object(s->cid, s->subdev); while (subdev && subdev->handle != obj->parent) subdev = subdev->parent_object; if (!subdev) { mmt_error("nvrm_ioctl_host_map: subdev 0x%08x is not an ancestor of object's parent (0x%08x)\n", s->subdev, obj->parent); return; } }*/ host_map(obj, fd, s->foffset, s->base, s->limit + 1, s->subdev, -1); }
static void handle_nvrm_ioctl_vspace_map(uint32_t fd, struct nvrm_ioctl_vspace_map *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_map: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } struct gpu_mapping *mapping = calloc(sizeof(struct gpu_mapping), 1); mapping->fd = fd; mapping->dev = s->dev; mapping->vspace = s->vspace; mapping->address = s->addr; mapping->object_offset = s->base; mapping->length = s->size; if (s->size > obj->length) { obj->data = realloc(obj->data, s->size); memset(obj->data + obj->length, 0, s->size - obj->length); obj->length = s->size; } mapping->object = obj; mapping->next = obj->gpu_mappings; obj->gpu_mappings = mapping; }
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 handle_nvrm_ioctl_create_dma(uint32_t fd, struct nvrm_ioctl_create_dma *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); nvrm_add_object(fd, s->cid, s->parent, s->handle, s->cls); }
static void handle_nvrm_ioctl_destroy(uint32_t fd, struct nvrm_ioctl_destroy *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); nvrm_destroy_gpu_object(fd, s->cid, s->parent, s->handle); }
static void handle_nvrm_ioctl_create_unk34(uint32_t fd, struct nvrm_ioctl_create_unk34 *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); nvrm_add_object(fd, s->cid, s->parent, s->handle, 0xffffffff);//TODO:class }
static void handle_nvrm_ioctl_create_simple(uint32_t fd, struct nvrm_ioctl_create_simple *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); struct gpu_object *obj = nvrm_add_object(fd, s->cid, s->parent, s->handle, s->cls); pushbuf_add_object(s->handle, s->cls, obj); }
static void handle_nvrm_ioctl_create(uint32_t fd, struct nvrm_ioctl_create *s, struct mmt_memory_dump *args, int argc) { if (s->status != NVRM_STATUS_SUCCESS) return; uint32_t cid = s->cid; uint32_t parent = s->parent; uint32_t handle = s->handle; struct mmt_buf *data = NULL; if (s->ptr) data = find_ptr(s->ptr, args, argc); if (handle == 0) { if (!data || data->len < 4) { mmt_error("\"create cid\" without data - probably because this trace was obtained by old mmt version (before Sep 6 2014)%s\n", ""); cid_not_found++; return; } cid = parent = handle = ((uint32_t *)data->data)[0]; } check_cid(cid); struct gpu_object *obj = nvrm_add_object(fd, cid, parent, handle, s->cls); pushbuf_add_object(handle, s->cls, obj); if (is_fifo_ib_class(s->cls)) { if (data) { struct fifo_state *state = get_fifo_state(obj); struct nvrm_create_fifo_ib *create_data = (void *)data->data; state->ib.addr = create_data->ib_addr; state->ib.entries = create_data->ib_entries; } } else if (is_fifo_dma_class(s->cls)) { if (data) { struct fifo_state *state = get_fifo_state(obj); struct nvrm_create_fifo_dma *create_data = (void *)data->data; state->user.addr = create_data->user_addr; } } }
static void handle_nvrm_ioctl_host_map56(uint32_t fd, struct nvrm_ioctl_host_map56 *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_map56: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } host_map(obj, fd, s->foffset, 0, s->length, s->subdev, s->map_id); }
static void handle_nvrm_ioctl_create_vspace56(uint32_t fd, struct nvrm_ioctl_create_vspace56 *s) { if (s->status != NVRM_STATUS_SUCCESS) return; check_cid(s->cid); struct gpu_object *obj = nvrm_add_object(fd, s->cid, s->parent, s->handle, s->cls); if (!obj) { mmt_error("nvrm_ioctl_create_vspace56: cannot find object 0x%08x 0x%08x\n", s->cid, s->handle); return; } if (s->map_id) host_map(obj, fd, 0, 0, s->limit + 1, 0, s->map_id); }
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(); }