diff options
Diffstat (limited to 'src/gallium/drivers/vc4/kernel/vc4_gem.c')
-rw-r--r-- | src/gallium/drivers/vc4/kernel/vc4_gem.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/kernel/vc4_gem.c b/src/gallium/drivers/vc4/kernel/vc4_gem.c new file mode 100644 index 00000000000..1ea17aa4e8c --- /dev/null +++ b/src/gallium/drivers/vc4/kernel/vc4_gem.c @@ -0,0 +1,147 @@ +/* + * Copyright © 2014 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef USE_VC4_SIMULATOR + +#include "vc4_drv.h" + +int +vc4_cl_validate(struct drm_device *dev, struct exec_info *exec) +{ + struct drm_vc4_submit_cl *args = exec->args; + void *temp = NULL; + void *bin, *render; + int ret = 0; + uint32_t bin_offset = 0; + uint32_t render_offset = bin_offset + args->bin_cl_size; + uint32_t shader_rec_offset = roundup(render_offset + + args->render_cl_size, 16); + uint32_t uniforms_offset = shader_rec_offset + args->shader_rec_size; + uint32_t exec_size = uniforms_offset + args->uniforms_size; + uint32_t temp_size = exec_size + (sizeof(struct vc4_shader_state) * + args->shader_rec_count); + + if (shader_rec_offset < render_offset || + uniforms_offset < shader_rec_offset || + exec_size < uniforms_offset || + args->shader_rec_count >= (UINT_MAX / + sizeof(struct vc4_shader_state)) || + temp_size < exec_size) { + DRM_ERROR("overflow in exec arguments\n"); + goto fail; + } + + /* Allocate space where we'll store the copied in user command lists + * and shader records. + * + * We don't just copy directly into the BOs because we need to + * read the contents back for validation, and I think the + * bo->vaddr is uncached access. + */ + temp = kmalloc(temp_size, GFP_KERNEL); + if (!temp) { + DRM_ERROR("Failed to allocate storage for copying " + "in bin/render CLs.\n"); + ret = -ENOMEM; + goto fail; + } + bin = temp + bin_offset; + render = temp + render_offset; + exec->shader_rec_u = temp + shader_rec_offset; + exec->uniforms_u = temp + uniforms_offset; + exec->shader_state = temp + exec_size; + exec->shader_state_size = args->shader_rec_count; + + ret = copy_from_user(bin, args->bin_cl, args->bin_cl_size); + if (ret) { + DRM_ERROR("Failed to copy in bin cl\n"); + goto fail; + } + + ret = copy_from_user(render, args->render_cl, args->render_cl_size); + if (ret) { + DRM_ERROR("Failed to copy in render cl\n"); + goto fail; + } + + ret = copy_from_user(exec->shader_rec_u, args->shader_rec, + args->shader_rec_size); + if (ret) { + DRM_ERROR("Failed to copy in shader recs\n"); + goto fail; + } + + ret = copy_from_user(exec->uniforms_u, args->uniforms, + args->uniforms_size); + if (ret) { + DRM_ERROR("Failed to copy in uniforms cl\n"); + goto fail; + } + + exec->exec_bo = drm_gem_cma_create(dev, exec_size); +#if 0 + if (IS_ERR(exec->exec_bo)) { + DRM_ERROR("Couldn't allocate BO for exec\n"); + ret = PTR_ERR(exec->exec_bo); + exec->exec_bo = NULL; + goto fail; + } +#endif + + exec->ct0ca = exec->exec_bo->paddr + bin_offset; + exec->ct1ca = exec->exec_bo->paddr + render_offset; + + exec->shader_rec_v = exec->exec_bo->vaddr + shader_rec_offset; + exec->shader_rec_p = exec->exec_bo->paddr + shader_rec_offset; + exec->shader_rec_size = args->shader_rec_size; + + exec->uniforms_v = exec->exec_bo->vaddr + uniforms_offset; + exec->uniforms_p = exec->exec_bo->paddr + uniforms_offset; + exec->uniforms_size = args->uniforms_size; + + ret = vc4_validate_cl(dev, + exec->exec_bo->vaddr + bin_offset, + bin, + args->bin_cl_size, + true, + exec); + if (ret) + goto fail; + + ret = vc4_validate_cl(dev, + exec->exec_bo->vaddr + render_offset, + render, + args->render_cl_size, + false, + exec); + if (ret) + goto fail; + + ret = vc4_validate_shader_recs(dev, exec); + +fail: + kfree(temp); + return ret; +} + +#endif /* USE_VC4_SIMULATOR */ |