static int vc4_simulator_pin_bos(struct drm_device *dev, struct vc4_exec_info *exec) { struct drm_vc4_submit_cl *args = exec->args; struct vc4_context *vc4 = dev->vc4; struct vc4_bo **bos = vc4->bo_pointers.base; exec->bo_count = args->bo_handle_count; exec->bo = calloc(exec->bo_count, sizeof(void *)); for (int i = 0; i < exec->bo_count; i++) { struct vc4_bo *bo = bos[i]; struct drm_gem_cma_object *obj = vc4_wrap_bo_with_cma(dev, bo); struct drm_vc4_bo *drm_bo = to_vc4_bo(&obj->base); #if 0 fprintf(stderr, "bo hindex %d: %s\n", i, bo->name); #endif vc4_bo_map(bo); memcpy(obj->vaddr, bo->map, bo->size); exec->bo[i] = obj; /* The kernel does this validation at shader create ioctl * time. */ if (strcmp(bo->name, "code") == 0) { drm_bo->validated_shader = vc4_validate_shader(obj); if (!drm_bo->validated_shader) abort(); } } return 0; }
int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_vc4_create_shader_bo *args = data; struct vc4_bo *bo = NULL; int ret; if (args->size == 0) return -EINVAL; if (args->size % sizeof(u64) != 0) return -EINVAL; if (args->flags != 0) { DRM_INFO("Unknown flags set: 0x%08x\n", args->flags); return -EINVAL; } if (args->pad != 0) { DRM_INFO("Pad set: 0x%08x\n", args->pad); return -EINVAL; } bo = vc4_bo_create(dev, args->size, true); if (IS_ERR(bo)) return PTR_ERR(bo); if (copy_from_user(bo->base.vaddr, (void __user *)(uintptr_t)args->data, args->size)) { ret = -EFAULT; goto fail; } /* Clear the rest of the memory from allocating from the BO * cache. */ memset(bo->base.vaddr + args->size, 0, bo->base.base.size - args->size); bo->validated_shader = vc4_validate_shader(&bo->base); if (!bo->validated_shader) { ret = -EINVAL; goto fail; } /* We have to create the handle after validation, to avoid * races for users to do doing things like mmap the shader BO. */ ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle); fail: drm_gem_object_unreference_unlocked(&bo->base.base); return ret; }