1fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz/************************************************************************** 2fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 3fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA 4fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * All Rights Reserved. 5fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 6fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Permission is hereby granted, free of charge, to any person obtaining a 7fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * copy of this software and associated documentation files (the 8fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * "Software"), to deal in the Software without restriction, including 9fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * without limitation the rights to use, copy, modify, merge, publish, 10fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * distribute, sub license, and/or sell copies of the Software, and to 11fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * permit persons to whom the Software is furnished to do so, subject to 12fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * the following conditions: 13fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 14fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * The above copyright notice and this permission notice (including the 15fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * next paragraph) shall be included in all copies or substantial portions 16fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * of the Software. 17fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 18fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * USE OR OTHER DEALINGS IN THE SOFTWARE. 25fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 26fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz **************************************************************************/ 27fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 28fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "vmwgfx_drv.h" 29fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "vmwgfx_reg.h" 30760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/ttm/ttm_bo_api.h> 31760285e7e7ab282c25b5e90816f7c47000557f4fDavid Howells#include <drm/ttm/ttm_placement.h> 32fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 33c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom#define VMW_RES_HT_ORDER 12 34c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 35c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 36c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * struct vmw_resource_relocation - Relocation info for resources 37c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 38c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @head: List head for the software context's relocation list. 39c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @res: Non-ref-counted pointer to the resource. 40c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @offset: Offset of 4 byte entries into the command buffer where the 41c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * id that needs fixup is located. 42c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 43c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstruct vmw_resource_relocation { 44c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct list_head head; 45c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom const struct vmw_resource *res; 46c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom unsigned long offset; 47c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom}; 48c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 49c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 50c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * struct vmw_resource_val_node - Validation info for resources 51c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 52c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @head: List head for the software context's resource list. 53c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @hash: Hash entry for quick resouce to val_node lookup. 54c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @res: Ref-counted pointer to the resource. 55c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @switch_backup: Boolean whether to switch backup buffer on unreserve. 56c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @new_backup: Refcounted pointer to the new backup buffer. 57b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom * @staged_bindings: If @res is a context, tracks bindings set up during 58b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom * the command batch. Otherwise NULL. 59c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @new_backup_offset: New backup buffer offset if @new_backup is non-NUll. 60c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @first_usage: Set to true the first time the resource is referenced in 61c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * the command stream. 62c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @no_buffer_needed: Resources do not need to allocate buffer backup on 63c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * reservation. The command stream will provide one. 64c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 65c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstruct vmw_resource_val_node { 66c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct list_head head; 67c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct drm_hash_item hash; 68c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *res; 69c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_dma_buffer *new_backup; 70b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom struct vmw_ctx_binding_state *staged_bindings; 71c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom unsigned long new_backup_offset; 72c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom bool first_usage; 73c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom bool no_buffer_needed; 74c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom}; 75c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 76c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 77c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom * struct vmw_cmd_entry - Describe a command for the verifier 78c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom * 79c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom * @user_allow: Whether allowed from the execbuf ioctl. 80c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom * @gb_disable: Whether disabled if guest-backed objects are available. 81c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom * @gb_enable: Whether enabled iff guest-backed objects are available. 82c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom */ 83c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstromstruct vmw_cmd_entry { 84c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom int (*func) (struct vmw_private *, struct vmw_sw_context *, 85c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom SVGA3dCmdHeader *); 86c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom bool user_allow; 87c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom bool gb_disable; 88c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom bool gb_enable; 89c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom}; 90c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom 91c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom#define VMW_CMD_DEF(_cmd, _func, _user_allow, _gb_disable, _gb_enable) \ 92c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom [(_cmd) - SVGA_3D_CMD_BASE] = {(_func), (_user_allow),\ 93c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom (_gb_disable), (_gb_enable)} 94c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom 95c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom/** 96c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_unreserve - unreserve resources previously reserved for 97c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * command submission. 98c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 99c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @list_head: list of resources to unreserve. 100c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @backoff: Whether command submission failed. 101c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 102c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic void vmw_resource_list_unreserve(struct list_head *list, 103c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom bool backoff) 104c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 105c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *val; 106c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 107c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry(val, list, head) { 108c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *res = val->res; 109c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_dma_buffer *new_backup = 110c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom backoff ? NULL : val->new_backup; 111c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 112173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom /* 113173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom * Transfer staged context bindings to the 114173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom * persistent context binding tracker. 115173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom */ 116b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (unlikely(val->staged_bindings)) { 11776c7d18bcddc9794f898ebdee44a3160c636da9cThomas Hellstrom if (!backoff) { 11876c7d18bcddc9794f898ebdee44a3160c636da9cThomas Hellstrom vmw_context_binding_state_transfer 11976c7d18bcddc9794f898ebdee44a3160c636da9cThomas Hellstrom (val->res, val->staged_bindings); 12076c7d18bcddc9794f898ebdee44a3160c636da9cThomas Hellstrom } 121b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom kfree(val->staged_bindings); 122b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom val->staged_bindings = NULL; 123b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 124c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_unreserve(res, new_backup, 125c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom val->new_backup_offset); 126c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_dmabuf_unreference(&val->new_backup); 127c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 128c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 129c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 130c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 131c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 132c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_val_add - Add a resource to the software context's 133c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * resource list if it's not already on it. 134c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 135c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: Pointer to the software context. 136c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @res: Pointer to the resource. 137c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @p_node On successful return points to a valid pointer to a 138c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * struct vmw_resource_val_node, if non-NULL on entry. 139c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 140c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_resource_val_add(struct vmw_sw_context *sw_context, 141c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *res, 142c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node **p_node) 143c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 144c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *node; 145c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct drm_hash_item *hash; 146c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 147c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 148c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) res, 149c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &hash) == 0)) { 150c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node = container_of(hash, struct vmw_resource_val_node, hash); 151c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node->first_usage = false; 152c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(p_node != NULL)) 153c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom *p_node = node; 154c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return 0; 155c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 156c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 157c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node = kzalloc(sizeof(*node), GFP_KERNEL); 158c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(node == NULL)) { 159c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Failed to allocate a resource validation " 160c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom "entry.\n"); 161c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return -ENOMEM; 162c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 163c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 164c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node->hash.key = (unsigned long) res; 165c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = drm_ht_insert_item(&sw_context->res_ht, &node->hash); 166c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) { 167c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Failed to initialize a resource validation " 168c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom "entry.\n"); 169c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom kfree(node); 170c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 171c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 172c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_add_tail(&node->head, &sw_context->resource_list); 173c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node->res = vmw_resource_reference(res); 174c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom node->first_usage = true; 175c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 176c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(p_node != NULL)) 177c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom *p_node = node; 178c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 179c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return 0; 180c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 181c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 182c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 18330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * vmw_resource_context_res_add - Put resources previously bound to a context on 18430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * the validation list 18530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * 18630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * @dev_priv: Pointer to a device private structure 18730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * @sw_context: Pointer to a software context used for this command submission 18830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * @ctx: Pointer to the context resource 18930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * 19030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * This function puts all resources that were previously bound to @ctx on 19130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * the resource validation list. This is part of the context state reemission 19230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom */ 19330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstromstatic int vmw_resource_context_res_add(struct vmw_private *dev_priv, 19430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct vmw_sw_context *sw_context, 19530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct vmw_resource *ctx) 19630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom{ 19730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct list_head *binding_list; 19830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct vmw_ctx_binding *entry; 19930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom int ret = 0; 20030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct vmw_resource *res; 20130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 20230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom mutex_lock(&dev_priv->binding_mutex); 20330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom binding_list = vmw_context_binding_list(ctx); 20430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 20530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom list_for_each_entry(entry, binding_list, ctx_list) { 20630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom res = vmw_resource_reference_unless_doomed(entry->bi.res); 20730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (unlikely(res == NULL)) 20830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom continue; 20930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 21030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom ret = vmw_resource_val_add(sw_context, entry->bi.res, NULL); 21130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom vmw_resource_unreference(&res); 21230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (unlikely(ret != 0)) 21330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom break; 21430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom } 21530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 21630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom mutex_unlock(&dev_priv->binding_mutex); 21730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom return ret; 21830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom} 21930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 22030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom/** 221c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_relocation_add - Add a relocation to the relocation list 222c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 223c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @list: Pointer to head of relocation list. 224c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @res: The resource. 225c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @offset: Offset into the command buffer currently being parsed where the 226c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * id that needs fixup is located. Granularity is 4 bytes. 227c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 228c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_resource_relocation_add(struct list_head *list, 229c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom const struct vmw_resource *res, 230c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom unsigned long offset) 231c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 232c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_relocation *rel; 233c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 234c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rel = kmalloc(sizeof(*rel), GFP_KERNEL); 235c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(rel == NULL)) { 236c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Failed to allocate a resource relocation.\n"); 237c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return -ENOMEM; 238c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 239c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 240c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rel->res = res; 241c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rel->offset = offset; 242c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_add_tail(&rel->head, list); 243c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 244c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return 0; 245c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 246c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 247c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 248c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_relocations_free - Free all relocations on a list 249c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 250c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @list: Pointer to the head of the relocation list. 251c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 252c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic void vmw_resource_relocations_free(struct list_head *list) 253c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 254c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_relocation *rel, *n; 255c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 256c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry_safe(rel, n, list, head) { 257c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_del(&rel->head); 258c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom kfree(rel); 259c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 260c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 261c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 262c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 263c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_relocations_apply - Apply all relocations on a list 264c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 265c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @cb: Pointer to the start of the command buffer bein patch. This need 266c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * not be the same buffer as the one being parsed when the relocation 267c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * list was built, but the contents must be the same modulo the 268c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * resource ids. 269c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @list: Pointer to the head of the relocation list. 270c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 271c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic void vmw_resource_relocations_apply(uint32_t *cb, 272c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct list_head *list) 273c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 274c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_relocation *rel; 275c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 276d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom list_for_each_entry(rel, list, head) { 277d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (likely(rel->res != NULL)) 278d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cb[rel->offset] = rel->res->id; 279d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom else 280d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cb[rel->offset] = SVGA_3D_CMD_NOP; 281d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom } 282c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 283c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 284fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_invalid(struct vmw_private *dev_priv, 285fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 286fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 287fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 288fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return capable(CAP_SYS_ADMIN) ? : -EINVAL; 289fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 290fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 291fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_ok(struct vmw_private *dev_priv, 292fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 293fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 294fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 295fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 296fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 297fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 298e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 299e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_bo_to_validate_list - add a bo to a validate list 300e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 301e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @sw_context: The software context used for this command submission batch. 302e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @bo: The buffer object to add. 30396c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom * @validate_as_mob: Validate this buffer as a MOB. 304e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @p_val_node: If non-NULL Will be updated with the validate node number 305e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * on return. 306e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 307e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * Returns -EINVAL if the limit of number of buffer objects per command 308e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * submission is reached. 309e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 310e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context, 311e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_buffer_object *bo, 31296c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom bool validate_as_mob, 313e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom uint32_t *p_val_node) 314e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 315e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom uint32_t val_node; 316c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_validate_buffer *vval_buf; 317e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_validate_buffer *val_buf; 318c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct drm_hash_item *hash; 319c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 320e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 321c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) bo, 322c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &hash) == 0)) { 323c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vval_buf = container_of(hash, struct vmw_validate_buffer, 324c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom hash); 32596c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom if (unlikely(vval_buf->validate_as_mob != validate_as_mob)) { 32696c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom DRM_ERROR("Inconsistent buffer usage.\n"); 32796c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom return -EINVAL; 32896c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom } 329c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom val_buf = &vval_buf->base; 330c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom val_node = vval_buf - sw_context->val_bufs; 331c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } else { 332c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom val_node = sw_context->cur_val_buf; 333c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(val_node >= VMWGFX_MAX_VALIDATIONS)) { 334c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Max number of DMA buffers per submission " 335c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom "exceeded.\n"); 336c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return -EINVAL; 337c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 338c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vval_buf = &sw_context->val_bufs[val_node]; 339c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vval_buf->hash.key = (unsigned long) bo; 340c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = drm_ht_insert_item(&sw_context->res_ht, &vval_buf->hash); 341c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) { 342c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Failed to initialize a buffer validation " 343c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom "entry.\n"); 344c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 345c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 346c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ++sw_context->cur_val_buf; 347c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom val_buf = &vval_buf->base; 348e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom val_buf->bo = ttm_bo_reference(bo); 349ae9c0af2c0ea92e57013ab2dd7271ba7d6b2a833Christian König val_buf->shared = false; 350e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom list_add_tail(&val_buf->head, &sw_context->validate_nodes); 35196c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom vval_buf->validate_as_mob = validate_as_mob; 352e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 353e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 354e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (p_val_node) 355e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom *p_val_node = val_node; 356e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 357e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return 0; 358e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 359e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 360c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 361c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resources_reserve - Reserve all resources on the sw_context's 362c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * resource list. 363c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 364c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: Pointer to the software context. 365c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 366c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Note that since vmware's command submission currently is protected by 367c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * the cmdbuf mutex, no fancy deadlock avoidance is required for resources, 368c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * since only a single thread at once will attempt this. 369c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 370c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_resources_reserve(struct vmw_sw_context *sw_context) 371fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 372c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *val; 373fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 374fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 375c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry(val, &sw_context->resource_list, head) { 376c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *res = val->res; 377fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 378c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_resource_reserve(res, val->no_buffer_needed); 379c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 380c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 381c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 382c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (res->backup) { 383c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct ttm_buffer_object *bo = &res->backup->base; 384c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 385c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_bo_to_validate_list 38696c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom (sw_context, bo, 38796c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom vmw_resource_needs_backup(res), NULL); 388c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 389c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 390c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 391c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 392fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 393c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return 0; 394c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 395fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 396c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 397c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resources_validate - Validate all resources on the sw_context's 398c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * resource list. 399c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 400c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: Pointer to the software context. 401c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 402c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Before this function is called, all resource backup buffers must have 403c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * been validated. 404c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 405c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_resources_validate(struct vmw_sw_context *sw_context) 406c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 407c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *val; 408c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 409c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 410c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry(val, &sw_context->resource_list, head) { 411c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *res = val->res; 412f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom 413c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_resource_validate(res); 414c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) { 415c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (ret != -ERESTARTSYS) 416c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Failed to validate resource.\n"); 417c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 418c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 419c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 420f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom return 0; 421fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 422fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 42318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 42418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom/** 42518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * vmw_cmd_res_reloc_add - Add a resource to a software context's 42618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * relocation- and validation lists. 42718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * 42818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @dev_priv: Pointer to a struct vmw_private identifying the device. 42918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @sw_context: Pointer to the software context. 43018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @res_type: Resource type. 43118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @id_loc: Pointer to where the id that needs translation is located. 43218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @res: Valid pointer to a struct vmw_resource. 43318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * @p_val: If non null, a pointer to the struct vmw_resource_validate_node 43418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * used for this resource is returned here. 43518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom */ 43618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstromstatic int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, 43718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_sw_context *sw_context, 43818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom enum vmw_res_type res_type, 43918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom uint32_t *id_loc, 44018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource *res, 44118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node **p_val) 44218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom{ 44318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom int ret; 44418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node *node; 44518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 44618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom *p_val = NULL; 44718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_resource_relocation_add(&sw_context->res_relocations, 44818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom res, 44918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom id_loc - sw_context->buf_start); 45018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (unlikely(ret != 0)) 4519f9cb84f416f07f57d75789d77e7d47d6141f44eThomas Hellstrom return ret; 45218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 45318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_resource_val_add(sw_context, res, &node); 45418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (unlikely(ret != 0)) 4559f9cb84f416f07f57d75789d77e7d47d6141f44eThomas Hellstrom return ret; 45618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 45718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (res_type == vmw_res_context && dev_priv->has_mob && 45818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom node->first_usage) { 45918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 46018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom /* 46118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * Put contexts first on the list to be able to exit 46218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * list traversal for contexts early. 46318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom */ 46418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom list_del(&node->head); 46518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom list_add(&node->head, &sw_context->resource_list); 46618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 46718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_resource_context_res_add(dev_priv, sw_context, res); 46818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (unlikely(ret != 0)) 4699f9cb84f416f07f57d75789d77e7d47d6141f44eThomas Hellstrom return ret; 47018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom node->staged_bindings = 47118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); 47218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (node->staged_bindings == NULL) { 47318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom DRM_ERROR("Failed to allocate context binding " 47418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom "information.\n"); 4759f9cb84f416f07f57d75789d77e7d47d6141f44eThomas Hellstrom return -ENOMEM; 47618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom } 47718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom INIT_LIST_HEAD(&node->staged_bindings->list); 47818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom } 47918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 48018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (p_val) 48118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom *p_val = node; 48218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 4839f9cb84f416f07f57d75789d77e7d47d6141f44eThomas Hellstrom return 0; 48418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom} 48518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 48618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 487c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 48818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom * vmw_cmd_res_check - Check that a resource is present and if so, put it 489c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * on the resource validate list unless it's already there. 490c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 491c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private structure. 492c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: Pointer to the software context. 493c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @res_type: Resource type. 494c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @converter: User-space visisble type specific information. 495d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @id_loc: Pointer to the location in the command buffer currently being 496c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * parsed from where the user-space resource id handle is located. 497d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @p_val: Pointer to pointer to resource validalidation node. Populated 498d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * on exit. 499c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 500d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstromstatic int 50118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstromvmw_cmd_res_check(struct vmw_private *dev_priv, 50218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_sw_context *sw_context, 50318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom enum vmw_res_type res_type, 50418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom const struct vmw_user_resource_conv *converter, 50518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom uint32_t *id_loc, 50618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node **p_val) 507fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 508c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_res_cache_entry *rcache = 509c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &sw_context->res_cache[res_type]; 510be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom struct vmw_resource *res; 511c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *node; 512c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 513be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 51418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (*id_loc == SVGA3D_INVALID_ID) { 515b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (p_val) 516b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom *p_val = NULL; 517b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (res_type == vmw_res_context) { 518b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom DRM_ERROR("Illegal context invalid id.\n"); 519b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom return -EINVAL; 520b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 5217a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return 0; 522b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 5237a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 524c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom /* 525c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Fastpath in case of repeated commands referencing the same 526c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * resource 527c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 5287a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 52918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (likely(rcache->valid && *id_loc == rcache->handle)) { 530c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom const struct vmw_resource *res = rcache->res; 531c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 532c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rcache->node->first_usage = false; 533c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (p_val) 534c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom *p_val = rcache->node; 535c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 536c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_resource_relocation_add 537c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom (&sw_context->res_relocations, res, 538d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom id_loc - sw_context->buf_start); 539be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom } 540be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 541c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_user_resource_lookup_handle(dev_priv, 542d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom sw_context->fp->tfile, 54318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom *id_loc, 544c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom converter, 545c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &res); 5465bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom if (unlikely(ret != 0)) { 547c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("Could not find or use resource 0x%08x.\n", 54818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom (unsigned) *id_loc); 549c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dump_stack(); 5505bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom return ret; 5515bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom } 5525bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom 553c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rcache->valid = true; 554c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rcache->res = res; 55518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom rcache->handle = *id_loc; 556c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 55718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, res_type, id_loc, 55818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom res, &node); 559c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 560c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_no_reloc; 561f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom 562c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom rcache->node = node; 563c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (p_val) 564c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom *p_val = node; 565c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_unreference(&res); 566f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom return 0; 567c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 568c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromout_no_reloc: 569c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG_ON(sw_context->error_resource != NULL); 570c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->error_resource = res; 571c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 572c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 573fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 574fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 575c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 57630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * vmw_rebind_contexts - Rebind all resources previously bound to 57730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * referenced contexts. 57830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * 57930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * @sw_context: Pointer to the software context. 58030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * 58130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom * Rebind context binding points that have been scrubbed because of eviction. 58230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom */ 58330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstromstatic int vmw_rebind_contexts(struct vmw_sw_context *sw_context) 58430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom{ 58530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom struct vmw_resource_val_node *val; 58630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom int ret; 58730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 58830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom list_for_each_entry(val, &sw_context->resource_list, head) { 58918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (unlikely(!val->staged_bindings)) 59018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom break; 59130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 59230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom ret = vmw_context_rebind_all(val->res); 59330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (unlikely(ret != 0)) { 59430f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (ret != -ERESTARTSYS) 59530f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom DRM_ERROR("Failed to rebind context.\n"); 59630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom return ret; 59730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom } 59830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom } 59930f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 60030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom return 0; 60130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom} 60230f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 60330f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom/** 604c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_cmd_cid_check - Check a command header for valid context information. 605c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 606c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private structure. 607c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: Pointer to the software context. 608c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @header: A command header with an embedded user-space context handle. 609c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 610c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Convenience function: Call vmw_cmd_res_check with the user-space context 611c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * handle embedded in @header. 612c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 613c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_cmd_cid_check(struct vmw_private *dev_priv, 614c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_sw_context *sw_context, 615c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader *header) 616c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 617c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_cid_cmd { 618c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader header; 6198e67bbbc51dbeaba480e83fe2162eb08083a0459Thomas Hellstrom uint32_t cid; 620c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } *cmd; 621c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 622c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom cmd = container_of(header, struct vmw_cid_cmd, header); 623c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 624c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_context_converter, &cmd->cid, NULL); 625c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 626fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 627fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, 628fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 629fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 630fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 631fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sid_cmd { 632fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader header; 633fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdSetRenderTarget body; 634fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } *cmd; 635b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom struct vmw_resource_val_node *ctx_node; 636173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom struct vmw_resource_val_node *res_node; 637fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 638fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 639b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom cmd = container_of(header, struct vmw_sid_cmd, header); 640b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 641b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 642b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom user_context_converter, &cmd->body.cid, 643b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom &ctx_node); 644fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 645fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 646fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 647c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 648c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 649173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom &cmd->body.target.sid, &res_node); 650b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (unlikely(ret != 0)) 651b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom return ret; 652b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 653b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (dev_priv->has_mob) { 654b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom struct vmw_ctx_bindinfo bi; 655b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 656b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.ctx = ctx_node->res; 657173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom bi.res = res_node ? res_node->res : NULL; 658b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.bt = vmw_ctx_binding_rt; 659b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.i1.rt_type = cmd->body.type; 660b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom return vmw_context_binding_add(ctx_node->staged_bindings, &bi); 661b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 662b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 663b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom return 0; 664fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 665fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 666fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, 667fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 668fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 669fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 670fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sid_cmd { 671fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader header; 672fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdSurfaceCopy body; 673fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } *cmd; 674fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 675fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 676fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd = container_of(header, struct vmw_sid_cmd, header); 677c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 678c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 679c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &cmd->body.src.sid, NULL); 680fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 681fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 682c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 683c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 684c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &cmd->body.dest.sid, NULL); 685fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 686fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 687fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, 688fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 689fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 690fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 691fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sid_cmd { 692fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader header; 693fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdSurfaceStretchBlt body; 694fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } *cmd; 695fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 696fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 697fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd = container_of(header, struct vmw_sid_cmd, header); 698c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 699c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 700c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &cmd->body.src.sid, NULL); 701fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 702fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 703c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 704c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 705c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &cmd->body.dest.sid, NULL); 706fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 707fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 708fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, 709fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 710fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 711fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 712fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sid_cmd { 713fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader header; 714fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdBlitSurfaceToScreen body; 715fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } *cmd; 716fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 717fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd = container_of(header, struct vmw_sid_cmd, header); 7180cff60c625131c64847debc2b4cee33ba33e8d8fJakob Bornecrantz 719c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 720c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 721c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &cmd->body.srcImage.sid, NULL); 722fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 723fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 724fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_present_check(struct vmw_private *dev_priv, 725fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 726fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header) 727fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 728fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sid_cmd { 729fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader header; 730fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdPresent body; 731fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } *cmd; 732fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 7335bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom 734fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd = container_of(header, struct vmw_sid_cmd, header); 7350cff60c625131c64847debc2b4cee33ba33e8d8fJakob Bornecrantz 736c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 737c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, &cmd->body.sid, 738c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom NULL); 739fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 740fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 741e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 742e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries. 743e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 744e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: The device private structure. 745e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @new_query_bo: The new buffer holding query results. 746e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @sw_context: The software context used for this command submission. 747e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 748e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function checks whether @new_query_bo is suitable for holding 749e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * query results, and if another buffer currently is pinned for query 750e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * results. If so, the function prepares the state of @sw_context for 751e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * switching pinned buffers after successful submission of the current 752c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * command batch. 753e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 754e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, 755e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_buffer_object *new_query_bo, 756e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct vmw_sw_context *sw_context) 757e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 758c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_res_cache_entry *ctx_entry = 759c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &sw_context->res_cache[vmw_res_context]; 760e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom int ret; 761c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 762c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG_ON(!ctx_entry->valid); 763c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->last_query_ctx = ctx_entry->res; 764e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 765e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(new_query_bo != sw_context->cur_query_bo)) { 766e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 767e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(new_query_bo->num_pages > 4)) { 768e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom DRM_ERROR("Query buffer too large.\n"); 769e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return -EINVAL; 770e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 771e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 772e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(sw_context->cur_query_bo != NULL)) { 773c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->needs_post_query_barrier = true; 774e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ret = vmw_bo_to_validate_list(sw_context, 775e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom sw_context->cur_query_bo, 77696c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom dev_priv->has_mob, NULL); 777e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 778e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return ret; 779e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 780e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom sw_context->cur_query_bo = new_query_bo; 781e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 782e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ret = vmw_bo_to_validate_list(sw_context, 783e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom dev_priv->dummy_query_bo, 78496c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom dev_priv->has_mob, NULL); 785e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 786e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return ret; 787e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 788e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 789e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 790e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return 0; 791e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 792e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 793e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 794e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 795e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_query_bo_switch_commit - Finalize switching pinned query buffer 796e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 797e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: The device private structure. 798e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @sw_context: The software context used for this command submission batch. 799e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 800e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function will check if we're switching query buffers, and will then, 801e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * issue a dummy occlusion query wait used as a query barrier. When the fence 802e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * object following that query wait has signaled, we are sure that all 803c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * preceding queries have finished, and the old query buffer can be unpinned. 804e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * However, since both the new query buffer and the old one are fenced with 805e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * that fence, we can do an asynchronus unpin now, and be sure that the 806e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * old query buffer won't be moved until the fence has signaled. 807e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 808e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * As mentioned above, both the new - and old query buffers need to be fenced 809e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * using a sequence emitted *after* calling this function. 810e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 811e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, 812e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct vmw_sw_context *sw_context) 813e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 814e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom /* 815e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * The validate list should still hold references to all 816e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * contexts here. 817e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 818e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 819c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (sw_context->needs_post_query_barrier) { 820c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_res_cache_entry *ctx_entry = 821c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &sw_context->res_cache[vmw_res_context]; 822c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *ctx; 823c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 824e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 825c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG_ON(!ctx_entry->valid); 826c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ctx = ctx_entry->res; 827e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 828e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id); 829e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 830e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 831e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom DRM_ERROR("Out of fifo space for dummy query.\n"); 832e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 833e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 834e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (dev_priv->pinned_bo != sw_context->cur_query_bo) { 835e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (dev_priv->pinned_bo) { 836e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_bo_pin(dev_priv->pinned_bo, false); 837e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&dev_priv->pinned_bo); 838e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 839e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 840c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (!sw_context->needs_post_query_barrier) { 841c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_bo_pin(sw_context->cur_query_bo, true); 842e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 843c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom /* 844c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * We pin also the dummy_query_bo buffer so that we 845c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * don't need to validate it when emitting 846c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * dummy queries in context destroy paths. 847c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 848e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 849c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_bo_pin(dev_priv->dummy_query_bo, true); 850c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dev_priv->dummy_query_bo_pinned = true; 851e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 852c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG_ON(sw_context->last_query_ctx == NULL); 853c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dev_priv->query_cid = sw_context->last_query_ctx->id; 854c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dev_priv->query_cid_valid = true; 855c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dev_priv->pinned_bo = 856c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ttm_bo_reference(sw_context->cur_query_bo); 857c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 858e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 859e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 860e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 861e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 862ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * vmw_translate_mob_pointer - Prepare to translate a user-space buffer 863ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * handle to a MOB id. 864ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * 865ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @dev_priv: Pointer to a device private structure. 866ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @sw_context: The software context used for this command batch validation. 867ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @id: Pointer to the user-space handle to be translated. 868ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @vmw_bo_p: Points to a location that, on successful return will carry 869ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * a reference-counted pointer to the DMA buffer identified by the 870ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * user-space handle in @id. 871ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * 872ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * This function saves information needed to translate a user-space buffer 873ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * handle to a MOB id. The translation does not take place immediately, but 874ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * during a call to vmw_apply_relocations(). This function builds a relocation 875ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * list and a list of buffers to validate. The former needs to be freed using 876ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * either vmw_apply_relocations() or vmw_free_relocations(). The latter 877ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * needs to be freed using vmw_clear_validations. 878ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom */ 879ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstromstatic int vmw_translate_mob_ptr(struct vmw_private *dev_priv, 880ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_sw_context *sw_context, 881ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGAMobId *id, 882ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_dma_buffer **vmw_bo_p) 883ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom{ 884ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_dma_buffer *vmw_bo = NULL; 885ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct ttm_buffer_object *bo; 886ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom uint32_t handle = *id; 887ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_relocation *reloc; 888ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom int ret; 889ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 890d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); 891ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) { 892ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom DRM_ERROR("Could not find or use MOB buffer.\n"); 893ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return -EINVAL; 894ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } 895ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom bo = &vmw_bo->base; 896ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 897ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { 898ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom DRM_ERROR("Max number relocations per submission" 899ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom " exceeded\n"); 900ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = -EINVAL; 901ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom goto out_no_reloc; 902ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } 903ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 904ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom reloc = &sw_context->relocs[sw_context->cur_reloc++]; 905ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom reloc->mob_loc = id; 906ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom reloc->location = NULL; 907ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 908ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_bo_to_validate_list(sw_context, bo, true, &reloc->index); 909ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) 910ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom goto out_no_reloc; 911ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 912ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom *vmw_bo_p = vmw_bo; 913ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return 0; 914ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 915ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstromout_no_reloc: 916ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 917ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom vmw_bo_p = NULL; 918ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 919ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom} 920ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 921ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom/** 922c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_translate_guest_pointer - Prepare to translate a user-space buffer 923c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * handle to a valid SVGAGuestPtr 924e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 925c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private structure. 926c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: The software context used for this command batch validation. 927c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @ptr: Pointer to the user-space handle to be translated. 928c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @vmw_bo_p: Points to a location that, on successful return will carry 929c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * a reference-counted pointer to the DMA buffer identified by the 930c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * user-space handle in @id. 931e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 932c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * This function saves information needed to translate a user-space buffer 933c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * handle to a valid SVGAGuestPtr. The translation does not take place 934c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * immediately, but during a call to vmw_apply_relocations(). 935c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * This function builds a relocation list and a list of buffers to validate. 936c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * The former needs to be freed using either vmw_apply_relocations() or 937c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_free_relocations(). The latter needs to be freed using 938c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_clear_validations. 939e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 9404e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstromstatic int vmw_translate_guest_ptr(struct vmw_private *dev_priv, 9414e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_sw_context *sw_context, 9424e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGAGuestPtr *ptr, 9434e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_dma_buffer **vmw_bo_p) 944fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 945fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_dma_buffer *vmw_bo = NULL; 946fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct ttm_buffer_object *bo; 9474e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom uint32_t handle = ptr->gmrId; 948fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_relocation *reloc; 9494e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom int ret; 950fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 951d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); 952fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 953fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Could not find or use GMR region.\n"); 954fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -EINVAL; 955fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 956fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz bo = &vmw_bo->base; 957fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 958fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { 9594e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom DRM_ERROR("Max number relocations per submission" 960fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz " exceeded\n"); 961fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = -EINVAL; 962fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_no_reloc; 963fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 964fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 965fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz reloc = &sw_context->relocs[sw_context->cur_reloc++]; 9664e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom reloc->location = ptr; 967fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 96896c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom ret = vmw_bo_to_validate_list(sw_context, bo, false, &reloc->index); 969e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 970fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_no_reloc; 971fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 9724e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom *vmw_bo_p = vmw_bo; 9734e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return 0; 9744e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 9754e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstromout_no_reloc: 9764e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 9774e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom vmw_bo_p = NULL; 9784e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 9794e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom} 9804e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 981c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 982ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * vmw_cmd_begin_gb_query - validate a SVGA_3D_CMD_BEGIN_GB_QUERY command. 983ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * 984ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @dev_priv: Pointer to a device private struct. 985ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @sw_context: The software context used for this command submission. 986ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @header: Pointer to the command header in the command stream. 987ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom */ 988ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstromstatic int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv, 989ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_sw_context *sw_context, 990ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader *header) 991ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom{ 992ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_begin_gb_query_cmd { 993ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 994ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdBeginGBQuery q; 995ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } *cmd; 996ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 997ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom cmd = container_of(header, struct vmw_begin_gb_query_cmd, 998ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom header); 999ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1000ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1001ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom user_context_converter, &cmd->q.cid, 1002ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom NULL); 1003ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom} 1004ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1005ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom/** 1006c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_cmd_begin_query - validate a SVGA_3D_CMD_BEGIN_QUERY command. 1007c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 1008c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1009c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: The software context used for this command submission. 1010c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1011c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 1012c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_cmd_begin_query(struct vmw_private *dev_priv, 1013c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_sw_context *sw_context, 1014c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader *header) 1015c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 1016c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_begin_query_cmd { 1017c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader header; 1018c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdBeginQuery q; 1019c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } *cmd; 1020c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1021c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom cmd = container_of(header, struct vmw_begin_query_cmd, 1022c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom header); 1023c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1024ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(dev_priv->has_mob)) { 1025ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct { 1026ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 1027ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdBeginGBQuery q; 1028ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } gb_cmd; 1029ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1030ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); 1031ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1032ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.id = SVGA_3D_CMD_BEGIN_GB_QUERY; 1033ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.size = cmd->header.size; 1034ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.cid = cmd->q.cid; 1035ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.type = cmd->q.type; 1036ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1037ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom memcpy(cmd, &gb_cmd, sizeof(*cmd)); 1038ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return vmw_cmd_begin_gb_query(dev_priv, sw_context, header); 1039ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } 1040ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1041c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1042c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_context_converter, &cmd->q.cid, 1043c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom NULL); 1044c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 1045c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1046c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 1047ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * vmw_cmd_end_gb_query - validate a SVGA_3D_CMD_END_GB_QUERY command. 1048ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * 1049ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1050ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @sw_context: The software context used for this command submission. 1051ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @header: Pointer to the command header in the command stream. 1052ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom */ 1053ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstromstatic int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, 1054ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_sw_context *sw_context, 1055ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader *header) 1056ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom{ 1057ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_dma_buffer *vmw_bo; 1058ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_query_cmd { 1059ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 1060ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdEndGBQuery q; 1061ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } *cmd; 1062ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom int ret; 1063ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1064ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom cmd = container_of(header, struct vmw_query_cmd, header); 1065ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 1066ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) 1067ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 1068ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1069ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_translate_mob_ptr(dev_priv, sw_context, 1070ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom &cmd->q.mobid, 1071ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom &vmw_bo); 1072ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) 1073ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 1074ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1075ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_query_bo_switch_prepare(dev_priv, &vmw_bo->base, sw_context); 1076ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1077ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 1078ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 1079ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom} 1080ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1081ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom/** 1082c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_cmd_end_query - validate a SVGA_3D_CMD_END_QUERY command. 1083c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 1084c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1085c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: The software context used for this command submission. 1086c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1087c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 10884e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstromstatic int vmw_cmd_end_query(struct vmw_private *dev_priv, 10894e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_sw_context *sw_context, 10904e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader *header) 10914e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom{ 10924e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_dma_buffer *vmw_bo; 10934e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_query_cmd { 10944e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader header; 10954e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdEndQuery q; 10964e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom } *cmd; 10974e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom int ret; 10984e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 10994e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom cmd = container_of(header, struct vmw_query_cmd, header); 1100ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (dev_priv->has_mob) { 1101ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct { 1102ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 1103ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdEndGBQuery q; 1104ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } gb_cmd; 1105ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1106ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); 1107ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1108ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.id = SVGA_3D_CMD_END_GB_QUERY; 1109ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.size = cmd->header.size; 1110ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.cid = cmd->q.cid; 1111ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.type = cmd->q.type; 1112ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.mobid = cmd->q.guestResult.gmrId; 1113ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.offset = cmd->q.guestResult.offset; 1114ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1115ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom memcpy(cmd, &gb_cmd, sizeof(*cmd)); 1116ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return vmw_cmd_end_gb_query(dev_priv, sw_context, header); 1117ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } 1118ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 11194e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 11204e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom if (unlikely(ret != 0)) 11214e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 11224e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 11234e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom ret = vmw_translate_guest_ptr(dev_priv, sw_context, 11244e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &cmd->q.guestResult, 11254e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &vmw_bo); 11264e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom if (unlikely(ret != 0)) 11274e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 11284e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 1129c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_query_bo_switch_prepare(dev_priv, &vmw_bo->base, sw_context); 1130e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 11314e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 1132e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return ret; 11334e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom} 1134fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1135ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom/** 1136ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * vmw_cmd_wait_gb_query - validate a SVGA_3D_CMD_WAIT_GB_QUERY command. 1137ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * 1138ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1139ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @sw_context: The software context used for this command submission. 1140ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom * @header: Pointer to the command header in the command stream. 1141ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom */ 1142ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstromstatic int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, 1143ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_sw_context *sw_context, 1144ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader *header) 1145ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom{ 1146ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_dma_buffer *vmw_bo; 1147ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct vmw_query_cmd { 1148ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 1149ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdWaitForGBQuery q; 1150ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } *cmd; 1151ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom int ret; 1152ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1153ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom cmd = container_of(header, struct vmw_query_cmd, header); 1154ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 1155ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) 1156ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 1157ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1158ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom ret = vmw_translate_mob_ptr(dev_priv, sw_context, 1159ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom &cmd->q.mobid, 1160ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom &vmw_bo); 1161ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (unlikely(ret != 0)) 1162ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return ret; 1163ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1164ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 1165ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return 0; 1166ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom} 1167ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1168ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom/** 1169c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_cmd_wait_query - validate a SVGA_3D_CMD_WAIT_QUERY command. 1170c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 1171c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1172c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: The software context used for this command submission. 1173c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1174c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 11754e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstromstatic int vmw_cmd_wait_query(struct vmw_private *dev_priv, 11764e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_sw_context *sw_context, 11774e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader *header) 11784e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom{ 11794e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_dma_buffer *vmw_bo; 11804e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_query_cmd { 11814e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader header; 11824e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdWaitForQuery q; 11834e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom } *cmd; 11844e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom int ret; 11854e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 11864e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom cmd = container_of(header, struct vmw_query_cmd, header); 1187ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom if (dev_priv->has_mob) { 1188ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom struct { 1189ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdHeader header; 1190ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom SVGA3dCmdWaitForGBQuery q; 1191ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } gb_cmd; 1192ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1193ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); 1194ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1195ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY; 1196ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.header.size = cmd->header.size; 1197ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.cid = cmd->q.cid; 1198ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.type = cmd->q.type; 1199ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.mobid = cmd->q.guestResult.gmrId; 1200ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom gb_cmd.q.offset = cmd->q.guestResult.offset; 1201ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 1202ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom memcpy(cmd, &gb_cmd, sizeof(*cmd)); 1203ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom return vmw_cmd_wait_gb_query(dev_priv, sw_context, header); 1204ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom } 1205ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom 12064e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 12074e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom if (unlikely(ret != 0)) 12084e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 12094e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 12104e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom ret = vmw_translate_guest_ptr(dev_priv, sw_context, 12114e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &cmd->q.guestResult, 12124e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &vmw_bo); 12134e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom if (unlikely(ret != 0)) 12144e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 12154e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 12164e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom vmw_dmabuf_unreference(&vmw_bo); 12174e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return 0; 12184e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom} 12194e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 12204e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstromstatic int vmw_cmd_dma(struct vmw_private *dev_priv, 12214e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_sw_context *sw_context, 12224e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader *header) 12234e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom{ 12244e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_dma_buffer *vmw_bo = NULL; 12254e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_surface *srf = NULL; 12264e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom struct vmw_dma_cmd { 12274e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdHeader header; 12284e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom SVGA3dCmdSurfaceDMA dma; 12294e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom } *cmd; 12304e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom int ret; 1231cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom SVGA3dCmdSurfaceDMASuffix *suffix; 1232cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom uint32_t bo_size; 12334e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 12344e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom cmd = container_of(header, struct vmw_dma_cmd, header); 1235cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + 1236cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom header->size - sizeof(*suffix)); 1237cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom 1238cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom /* Make sure device and verifier stays in sync. */ 1239cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom if (unlikely(suffix->suffixSize != sizeof(*suffix))) { 1240cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom DRM_ERROR("Invalid DMA suffix size.\n"); 1241cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom return -EINVAL; 1242cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom } 1243cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom 12444e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom ret = vmw_translate_guest_ptr(dev_priv, sw_context, 12454e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &cmd->dma.guest.ptr, 12464e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom &vmw_bo); 12474e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom if (unlikely(ret != 0)) 12484e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom return ret; 12494e4ddd47774313accc86b233d6ca2c6a9037a671Thomas Hellstrom 1250cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom /* Make sure DMA doesn't cross BO boundaries. */ 1251cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom bo_size = vmw_bo->base.num_pages * PAGE_SIZE; 1252cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) { 1253cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom DRM_ERROR("Invalid DMA offset.\n"); 1254cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom return -EINVAL; 1255cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom } 1256cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom 1257cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom bo_size -= cmd->dma.guest.ptr.offset; 1258cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom if (unlikely(suffix->maximumOffset > bo_size)) 1259cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom suffix->maximumOffset = bo_size; 1260cbd75e97a525e3819c02dc18bc2d67aa544c9e45Thomas Hellstrom 1261c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1262c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, &cmd->dma.host.sid, 1263c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom NULL); 12645bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom if (unlikely(ret != 0)) { 1265c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != -ERESTARTSYS)) 1266c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom DRM_ERROR("could not find surface for DMA.\n"); 1267c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_no_surface; 12685bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom } 12695bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom 1270c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); 1271f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom 1272d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, 1273d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom header); 1274fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1275c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromout_no_surface: 1276fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_dmabuf_unreference(&vmw_bo); 1277fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 1278fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 1279fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 12807a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstromstatic int vmw_cmd_draw(struct vmw_private *dev_priv, 12817a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom struct vmw_sw_context *sw_context, 12827a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdHeader *header) 12837a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom{ 12847a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom struct vmw_draw_cmd { 12857a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdHeader header; 12867a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdDrawPrimitives body; 12877a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } *cmd; 12887a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)( 12897a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom (unsigned long)header + sizeof(*cmd)); 12907a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dPrimitiveRange *range; 12917a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom uint32_t i; 12927a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom uint32_t maxnum; 12937a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom int ret; 12947a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 12957a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom ret = vmw_cmd_cid_check(dev_priv, sw_context, header); 12967a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(ret != 0)) 12977a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return ret; 12987a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 12997a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom cmd = container_of(header, struct vmw_draw_cmd, header); 13007a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl); 13017a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13027a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(cmd->body.numVertexDecls > maxnum)) { 13037a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom DRM_ERROR("Illegal number of vertex declarations.\n"); 13047a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return -EINVAL; 13057a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } 13067a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13077a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) { 1308c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1309c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 1310c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &decl->array.surfaceId, NULL); 13117a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(ret != 0)) 13127a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return ret; 13137a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } 13147a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13157a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom maxnum = (header->size - sizeof(cmd->body) - 13167a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range); 13177a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(cmd->body.numRanges > maxnum)) { 13187a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom DRM_ERROR("Illegal number of index ranges.\n"); 13197a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return -EINVAL; 13207a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } 13217a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13227a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom range = (SVGA3dPrimitiveRange *) decl; 13237a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom for (i = 0; i < cmd->body.numRanges; ++i, ++range) { 1324c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1325c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 1326c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom &range->indexArray.surfaceId, NULL); 13277a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(ret != 0)) 13287a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return ret; 13297a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } 13307a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return 0; 13317a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom} 13327a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13337a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13347a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstromstatic int vmw_cmd_tex_state(struct vmw_private *dev_priv, 13357a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom struct vmw_sw_context *sw_context, 13367a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdHeader *header) 13377a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom{ 13387a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom struct vmw_tex_state_cmd { 13397a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdHeader header; 13407a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dCmdSetTextureState state; 1341b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } *cmd; 13427a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13437a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dTextureState *last_state = (SVGA3dTextureState *) 13447a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom ((unsigned long) header + header->size + sizeof(header)); 13457a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom SVGA3dTextureState *cur_state = (SVGA3dTextureState *) 13467a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom ((unsigned long) header + sizeof(struct vmw_tex_state_cmd)); 1347b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom struct vmw_resource_val_node *ctx_node; 1348173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom struct vmw_resource_val_node *res_node; 13497a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom int ret; 13507a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 1351b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom cmd = container_of(header, struct vmw_tex_state_cmd, 1352b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom header); 1353b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 1354b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1355b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom user_context_converter, &cmd->state.cid, 1356b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom &ctx_node); 13577a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(ret != 0)) 13587a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return ret; 13597a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13607a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom for (; cur_state < last_state; ++cur_state) { 13617a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE)) 13627a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom continue; 13637a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 1364c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1365c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom user_surface_converter, 1366173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom &cur_state->value, &res_node); 13677a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(ret != 0)) 13687a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return ret; 1369b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 1370b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (dev_priv->has_mob) { 1371b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom struct vmw_ctx_bindinfo bi; 1372b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom 1373b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.ctx = ctx_node->res; 1374173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom bi.res = res_node ? res_node->res : NULL; 1375b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.bt = vmw_ctx_binding_tex; 1376b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom bi.i1.texture_stage = cur_state->stage; 1377b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom vmw_context_binding_add(ctx_node->staged_bindings, 1378b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom &bi); 1379b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 13807a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom } 13817a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13827a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom return 0; 13837a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom} 13847a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 13854084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantzstatic int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, 13864084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz struct vmw_sw_context *sw_context, 13874084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz void *buf) 13884084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz{ 13894084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz struct vmw_dma_buffer *vmw_bo; 13904084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz int ret; 13914084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 13924084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz struct { 13934084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz uint32_t header; 13944084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz SVGAFifoCmdDefineGMRFB body; 13954084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz } *cmd = buf; 13964084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 13974084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz ret = vmw_translate_guest_ptr(dev_priv, sw_context, 13984084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz &cmd->body.ptr, 13994084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz &vmw_bo); 14004084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz if (unlikely(ret != 0)) 14014084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return ret; 14024084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 14034084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz vmw_dmabuf_unreference(&vmw_bo); 14044084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 14054084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return ret; 14064084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz} 14074084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 1408c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 1409a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_switch_backup - Utility function to handle backup buffer switching 1410a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1411a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1412a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1413a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @res_type: The resource type. 1414a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @converter: Information about user-space binding for this resource type. 1415a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @res_id: Pointer to the user-space resource handle in the command stream. 1416a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @buf_id: Pointer to the user-space backup buffer handle in the command 1417a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * stream. 1418a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @backup_offset: Offset of backup into MOB. 1419a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1420a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * This function prepares for registering a switch of backup buffers 1421a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * in the resource metadata just prior to unreserving. 1422a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1423a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_switch_backup(struct vmw_private *dev_priv, 1424a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1425a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom enum vmw_res_type res_type, 1426a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom const struct vmw_user_resource_conv 1427a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom *converter, 1428a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom uint32_t *res_id, 1429a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom uint32_t *buf_id, 1430a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom unsigned long backup_offset) 1431a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1432a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom int ret; 1433a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_dma_buffer *dma_buf; 1434a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_resource_val_node *val_node; 1435a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1436a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, res_type, 1437a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom converter, res_id, &val_node); 1438a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom if (unlikely(ret != 0)) 1439a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return ret; 1440a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1441a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom ret = vmw_translate_mob_ptr(dev_priv, sw_context, buf_id, &dma_buf); 1442a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom if (unlikely(ret != 0)) 1443a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return ret; 1444a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1445a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom if (val_node->first_usage) 1446a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom val_node->no_buffer_needed = true; 1447a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1448a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom vmw_dmabuf_unreference(&val_node->new_backup); 1449a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom val_node->new_backup = dma_buf; 1450a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom val_node->new_backup_offset = backup_offset; 1451a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1452a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return 0; 1453a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1454a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1455a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1456a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_bind_gb_surface - Validate an SVGA_3D_CMD_BIND_GB_SURFACE 1457a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1458a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1459a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1460a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1461a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1462a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1463a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv, 1464a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1465a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1466a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1467a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_bind_gb_surface_cmd { 1468a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1469a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdBindGBSurface body; 1470a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1471a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1472a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_bind_gb_surface_cmd, header); 1473a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1474a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface, 1475a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1476a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.sid, &cmd->body.mobid, 1477a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 0); 1478a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1479a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1480a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1481a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_update_gb_image - Validate an SVGA_3D_CMD_UPDATE_GB_IMAGE 1482a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1483a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1484a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1485a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1486a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1487a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1488a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_update_gb_image(struct vmw_private *dev_priv, 1489a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1490a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1491a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1492a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1493a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1494a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdUpdateGBImage body; 1495a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1496a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1497a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1498a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1499a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1500a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1501a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.image.sid, NULL); 1502a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1503a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1504a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1505a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_update_gb_surface - Validate an SVGA_3D_CMD_UPDATE_GB_SURFACE 1506a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1507a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1508a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1509a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1510a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1511a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1512a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv, 1513a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1514a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1515a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1516a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1517a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1518a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdUpdateGBSurface body; 1519a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1520a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1521a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1522a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1523a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1524a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1525a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.sid, NULL); 1526a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1527a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1528a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1529a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_readback_gb_image - Validate an SVGA_3D_CMD_READBACK_GB_IMAGE 1530a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1531a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1532a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1533a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1534a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1535a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1536a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv, 1537a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1538a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1539a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1540a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1541a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1542a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdReadbackGBImage body; 1543a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1544a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1545a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1546a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1547a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1548a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1549a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.image.sid, NULL); 1550a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1551a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1552a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1553a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_readback_gb_surface - Validate an SVGA_3D_CMD_READBACK_GB_SURFACE 1554a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1555a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1556a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1557a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1558a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1559a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1560a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv, 1561a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1562a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1563a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1564a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1565a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1566a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdReadbackGBSurface body; 1567a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1568a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1569a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1570a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1571a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1572a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1573a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.sid, NULL); 1574a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1575a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1576a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1577a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_invalidate_gb_image - Validate an SVGA_3D_CMD_INVALIDATE_GB_IMAGE 1578a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * command 1579a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1580a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1581a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1582a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1583a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1584a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv, 1585a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1586a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1587a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1588a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1589a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1590a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdInvalidateGBImage body; 1591a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1592a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1593a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1594a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1595a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1596a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1597a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.image.sid, NULL); 1598a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1599a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1600a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1601a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * vmw_cmd_invalidate_gb_surface - Validate an 1602a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * SVGA_3D_CMD_INVALIDATE_GB_SURFACE command 1603a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * 1604a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1605a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @sw_context: The software context being used for this batch. 1606a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom * @header: Pointer to the command header in the command stream. 1607a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom */ 1608a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstromstatic int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, 1609a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_sw_context *sw_context, 1610a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader *header) 1611a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom{ 1612a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom struct vmw_gb_surface_cmd { 1613a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdHeader header; 1614a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom SVGA3dCmdInvalidateGBSurface body; 1615a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom } *cmd; 1616a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1617a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom cmd = container_of(header, struct vmw_gb_surface_cmd, header); 1618a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1619a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, 1620a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom user_surface_converter, 1621a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom &cmd->body.sid, NULL); 1622a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom} 1623a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom 1624d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1625d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom/** 1626d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * vmw_cmd_shader_define - Validate an SVGA_3D_CMD_SHADER_DEFINE 1627d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * command 1628d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * 1629d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1630d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @sw_context: The software context being used for this batch. 1631d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1632d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom */ 1633d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstromstatic int vmw_cmd_shader_define(struct vmw_private *dev_priv, 1634d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom struct vmw_sw_context *sw_context, 1635d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdHeader *header) 1636d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom{ 1637d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom struct vmw_shader_define_cmd { 1638d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdHeader header; 1639d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdDefineShader body; 1640d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom } *cmd; 1641d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom int ret; 1642d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom size_t size; 164318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node *val; 1644d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1645d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd = container_of(header, struct vmw_shader_define_cmd, 1646d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom header); 1647d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1648d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1649d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom user_context_converter, &cmd->body.cid, 165018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &val); 1651d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(ret != 0)) 1652d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return ret; 1653d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1654d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(!dev_priv->has_mob)) 1655d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return 0; 1656d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1657d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom size = cmd->header.size - sizeof(cmd->body); 165818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_compat_shader_add(dev_priv, 165918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_context_res_man(val->res), 1660d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd->body.shid, cmd + 1, 1661d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd->body.type, size, 166218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &sw_context->staged_cmd_res); 1663d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(ret != 0)) 1664d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return ret; 1665d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1666d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return vmw_resource_relocation_add(&sw_context->res_relocations, 1667d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom NULL, &cmd->header.id - 1668d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom sw_context->buf_start); 1669d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1670d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return 0; 1671d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom} 1672d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1673d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom/** 1674d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * vmw_cmd_shader_destroy - Validate an SVGA_3D_CMD_SHADER_DESTROY 1675d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * command 1676d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * 1677d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1678d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @sw_context: The software context being used for this batch. 1679d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1680d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom */ 1681d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstromstatic int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, 1682d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom struct vmw_sw_context *sw_context, 1683d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdHeader *header) 1684d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom{ 1685d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom struct vmw_shader_destroy_cmd { 1686d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdHeader header; 1687d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom SVGA3dCmdDestroyShader body; 1688d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom } *cmd; 1689d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom int ret; 169018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node *val; 1691d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1692d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd = container_of(header, struct vmw_shader_destroy_cmd, 1693d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom header); 1694d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1695d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1696d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom user_context_converter, &cmd->body.cid, 169718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &val); 1698d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(ret != 0)) 1699d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return ret; 1700d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1701d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(!dev_priv->has_mob)) 1702d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return 0; 1703d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 170418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_compat_shader_remove(vmw_context_res_man(val->res), 1705d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd->body.shid, 1706d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom cmd->body.type, 170718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &sw_context->staged_cmd_res); 1708d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom if (unlikely(ret != 0)) 1709d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return ret; 1710d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1711d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return vmw_resource_relocation_add(&sw_context->res_relocations, 1712d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom NULL, &cmd->header.id - 1713d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom sw_context->buf_start); 1714d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1715d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom return 0; 1716d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom} 1717d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom 1718a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom/** 1719c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER 1720c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * command 1721c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 1722c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 1723c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @sw_context: The software context being used for this batch. 1724c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @header: Pointer to the command header in the command stream. 1725c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 1726c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic int vmw_cmd_set_shader(struct vmw_private *dev_priv, 1727c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_sw_context *sw_context, 1728c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader *header) 1729c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 1730c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_set_shader_cmd { 1731c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdHeader header; 1732c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom SVGA3dCmdSetShader body; 1733c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } *cmd; 173418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource_val_node *ctx_node, *res_node = NULL; 173518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_ctx_bindinfo bi; 173618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom struct vmw_resource *res = NULL; 1737c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom int ret; 1738c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1739c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom cmd = container_of(header, struct vmw_set_shader_cmd, 1740c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom header); 1741c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1742b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 1743b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom user_context_converter, &cmd->body.cid, 1744b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom &ctx_node); 1745c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 1746c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom return ret; 1747c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 174818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (!dev_priv->has_mob) 174918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom return 0; 175018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 175118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (cmd->body.shid != SVGA3D_INVALID_ID) { 175218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom res = vmw_compat_shader_lookup 175318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom (vmw_context_res_man(ctx_node->res), 175418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom cmd->body.shid, 175518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom cmd->body.type); 175618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 175718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (!IS_ERR(res)) { 175818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_cmd_res_reloc_add(dev_priv, sw_context, 175918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_res_shader, 176018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &cmd->body.shid, res, 176118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &res_node); 176218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_resource_unreference(&res); 176318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (unlikely(ret != 0)) 176418e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom return ret; 176518e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom } 176618e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom } 176718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 176818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom if (!res_node) { 176918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, 177018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_res_shader, 177118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom user_shader_converter, 177218e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom &cmd->body.shid, &res_node); 1773b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (unlikely(ret != 0)) 1774b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom return ret; 1775b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom } 1776c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom 177718e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom bi.ctx = ctx_node->res; 177818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom bi.res = res_node ? res_node->res : NULL; 177918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom bi.bt = vmw_ctx_binding_shader; 178018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom bi.i1.shader_type = cmd->body.type; 178118e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom return vmw_context_binding_add(ctx_node->staged_bindings, &bi); 1782c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 1783c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 1784c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom/** 17850ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * vmw_cmd_set_shader_const - Validate an SVGA_3D_CMD_SET_SHADER_CONST 17860ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * command 17870ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * 17880ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * @dev_priv: Pointer to a device private struct. 17890ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * @sw_context: The software context being used for this batch. 17900ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom * @header: Pointer to the command header in the command stream. 17910ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom */ 17920ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstromstatic int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, 17930ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom struct vmw_sw_context *sw_context, 17940ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom SVGA3dCmdHeader *header) 17950ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom{ 17960ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom struct vmw_set_shader_const_cmd { 17970ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom SVGA3dCmdHeader header; 17980ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom SVGA3dCmdSetShaderConst body; 17990ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom } *cmd; 18000ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom int ret; 18010ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom 18020ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom cmd = container_of(header, struct vmw_set_shader_const_cmd, 18030ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom header); 18040ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom 18050ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, 18060ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom user_context_converter, &cmd->body.cid, 18070ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom NULL); 18080ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom if (unlikely(ret != 0)) 18090ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom return ret; 18100ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom 18110ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom if (dev_priv->has_mob) 18120ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom header->id = SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE; 18130ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom 18140ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom return 0; 18150ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom} 18160ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom 18170ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom/** 1818c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER 1819c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * command 1820c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * 1821c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * @dev_priv: Pointer to a device private struct. 1822c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * @sw_context: The software context being used for this batch. 1823c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom * @header: Pointer to the command header in the command stream. 1824c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom */ 1825c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstromstatic int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv, 1826c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom struct vmw_sw_context *sw_context, 1827c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom SVGA3dCmdHeader *header) 1828c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom{ 1829c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom struct vmw_bind_gb_shader_cmd { 1830c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom SVGA3dCmdHeader header; 1831c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom SVGA3dCmdBindGBShader body; 1832c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom } *cmd; 1833c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom 1834c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom cmd = container_of(header, struct vmw_bind_gb_shader_cmd, 1835c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom header); 1836c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom 1837c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader, 1838c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom user_shader_converter, 1839c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom &cmd->body.shid, &cmd->body.mobid, 1840c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom cmd->body.offsetInBytes); 1841c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom} 1842c74c162fd99fbe204fe67acd5ba40589c236df6cThomas Hellstrom 18434084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantzstatic int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, 18444084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz struct vmw_sw_context *sw_context, 18454084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz void *buf, uint32_t *size) 18464084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz{ 18474084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz uint32_t size_remaining = *size; 18484084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz uint32_t cmd_id; 18494084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 18504084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz cmd_id = le32_to_cpu(((uint32_t *)buf)[0]); 18514084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz switch (cmd_id) { 18524084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz case SVGA_CMD_UPDATE: 18534084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate); 18544084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz break; 18554084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz case SVGA_CMD_DEFINE_GMRFB: 18564084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB); 18574084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz break; 18584084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz case SVGA_CMD_BLIT_GMRFB_TO_SCREEN: 18594084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen); 18604084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz break; 18614084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz case SVGA_CMD_BLIT_SCREEN_TO_GMRFB: 18624084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen); 18634084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz break; 18644084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz default: 18654084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id); 18664084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return -EINVAL; 18674084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz } 18684084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 18694084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz if (*size > size_remaining) { 18704084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz DRM_ERROR("Invalid SVGA command (size mismatch):" 18714084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz " %u.\n", cmd_id); 18724084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return -EINVAL; 18734084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz } 18744084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 18750cff60c625131c64847debc2b4cee33ba33e8d8fJakob Bornecrantz if (unlikely(!sw_context->kernel)) { 18764084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id); 18774084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return -EPERM; 18784084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz } 18794084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 18804084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz if (cmd_id == SVGA_CMD_DEFINE_GMRFB) 18814084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf); 18824084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 18834084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return 0; 18844084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz} 1885fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 18864fbd9d2ec2f12ffb292c1489d1402e8b956afc01Thomas Hellstromstatic const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { 1887c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid, 1888c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1889c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid, 1890c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1891c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check, 1892c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1893c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check, 1894c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1895c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma, 1896c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1897c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid, 1898c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1899c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid, 1900c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1901c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check, 1902c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1903c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check, 1904c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1905c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check, 1906c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1907fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET, 1908c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_set_render_target_check, true, false, false), 1909c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state, 1910c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1911c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check, 1912c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1913c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check, 1914c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1915c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check, 1916c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1917c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check, 1918c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1919c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check, 1920c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1921c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check, 1922c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1923c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check, 1924c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1925d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_shader_define, 1926d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom true, false, false), 1927d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_shader_destroy, 1928d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom true, false, false), 1929c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader, 1930c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 19310ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_set_shader_const, 19320ccbbae43c2dfe45ded1d7ed59b8fc7ac8214fb0Thomas Hellstrom true, false, false), 1933c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw, 1934c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1935c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check, 1936c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1937c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_begin_query, 1938c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1939c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query, 1940c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1941c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query, 1942c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1943c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok, 1944c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, false), 1945fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, 1946c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_blt_surf_screen_check, false, false, false), 1947c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE_V2, &vmw_cmd_invalid, 1948c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1949c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_GENERATE_MIPMAPS, &vmw_cmd_invalid, 1950c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1951c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_ACTIVATE_SURFACE, &vmw_cmd_invalid, 1952c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1953c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEACTIVATE_SURFACE, &vmw_cmd_invalid, 1954c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1955c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SCREEN_DMA, &vmw_cmd_invalid, 1956c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1957c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_UNITY_SURFACE_COOKIE, &vmw_cmd_invalid, 1958c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1959c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_OPEN_CONTEXT_SURFACE, &vmw_cmd_invalid, 1960c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1961c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_BITBLT, &vmw_cmd_invalid, 1962c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1963c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_TRANSBLT, &vmw_cmd_invalid, 1964c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1965c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_STRETCHBLT, &vmw_cmd_invalid, 1966c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1967c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_COLORFILL, &vmw_cmd_invalid, 1968c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1969c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_ALPHABLEND, &vmw_cmd_invalid, 1970c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1971c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND, &vmw_cmd_invalid, 1972c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, false), 1973c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE, &vmw_cmd_invalid, 1974c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1975c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_READBACK_OTABLE, &vmw_cmd_invalid, 1976c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1977c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_MOB, &vmw_cmd_invalid, 1978c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1979c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_MOB, &vmw_cmd_invalid, 1980c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1981c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_REDEFINE_GB_MOB, &vmw_cmd_invalid, 1982c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1983c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING, &vmw_cmd_invalid, 1984c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1985c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE, &vmw_cmd_invalid, 1986c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1987c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SURFACE, &vmw_cmd_invalid, 1988c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1989c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SURFACE, &vmw_cmd_bind_gb_surface, 1990c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 1991c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_COND_BIND_GB_SURFACE, &vmw_cmd_invalid, 1992c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 1993c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_IMAGE, &vmw_cmd_update_gb_image, 1994c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 1995a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SURFACE, 1996c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_update_gb_surface, true, false, true), 1997a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE, 1998c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_readback_gb_image, true, false, true), 1999a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_SURFACE, 2000c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_readback_gb_surface, true, false, true), 2001a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE, 2002c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_invalidate_gb_image, true, false, true), 2003a97e21923b421993258e8487f2a5700c1ba3897fThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_SURFACE, 2004c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom &vmw_cmd_invalidate_gb_surface, true, false, true), 2005c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_CONTEXT, &vmw_cmd_invalid, 2006c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2007c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_CONTEXT, &vmw_cmd_invalid, 2008c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2009c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_CONTEXT, &vmw_cmd_invalid, 2010c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2011c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_CONTEXT, &vmw_cmd_invalid, 2012c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2013c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT, &vmw_cmd_invalid, 2014c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2015c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SHADER, &vmw_cmd_invalid, 2016c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2017c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SHADER, &vmw_cmd_bind_gb_shader, 2018c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 2019c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid, 2020c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2021f2a0dcb1aa23eea8f186b4773a653e61d509b17aThomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid, 20228ba07315d3ffcb7dfbb5143a3be03fe4af079969Thomas Hellstrom false, false, false), 2023c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query, 2024c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 2025c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_END_GB_QUERY, &vmw_cmd_end_gb_query, 2026c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 2027c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_GB_QUERY, &vmw_cmd_wait_gb_query, 2028c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 2029c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_NOP, &vmw_cmd_ok, 2030c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true), 2031c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_ENABLE_GART, &vmw_cmd_invalid, 2032c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2033c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DISABLE_GART, &vmw_cmd_invalid, 2034c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2035c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_MAP_MOB_INTO_GART, &vmw_cmd_invalid, 2036c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2037c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_UNMAP_GART_RANGE, &vmw_cmd_invalid, 2038c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2039c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET, &vmw_cmd_invalid, 2040c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2041c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET, &vmw_cmd_invalid, 2042c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2043c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SCREENTARGET, &vmw_cmd_invalid, 2044c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2045c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET, &vmw_cmd_invalid, 2046c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2047c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL, &vmw_cmd_invalid, 2048c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2049c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL, &vmw_cmd_invalid, 2050c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom false, false, true), 2051c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom VMW_CMD_DEF(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE, &vmw_cmd_cid_check, 2052c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom true, false, true) 2053fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz}; 2054fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2055fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_check(struct vmw_private *dev_priv, 2056fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 2057fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz void *buf, uint32_t *size) 2058fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2059fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz uint32_t cmd_id; 20607a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom uint32_t size_remaining = *size; 2061fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf; 2062fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 2063c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom const struct vmw_cmd_entry *entry; 2064c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom bool gb = dev_priv->capabilities & SVGA_CAP_GBOBJECTS; 2065fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 20664084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz cmd_id = le32_to_cpu(((uint32_t *)buf)[0]); 20674084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz /* Handle any none 3D commands */ 20684084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz if (unlikely(cmd_id < SVGA_CMD_MAX)) 20694084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size); 20704084fb89e6b463686219a2369d1d35e6b78f785dJakob Bornecrantz 2071fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2072fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd_id = le32_to_cpu(header->id); 2073fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader); 2074fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2075fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd_id -= SVGA_3D_CMD_BASE; 20767a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom if (unlikely(*size > size_remaining)) 2077c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_invalid; 20787a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom 2079fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE)) 2080c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_invalid; 2081c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom 2082c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom entry = &vmw_cmd_entries[cmd_id]; 208336e952c1ed8ca44bca245c465c8293e175dd9222Thomas Hellstrom if (unlikely(!entry->func)) 208436e952c1ed8ca44bca245c465c8293e175dd9222Thomas Hellstrom goto out_invalid; 208536e952c1ed8ca44bca245c465c8293e175dd9222Thomas Hellstrom 2086c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom if (unlikely(!entry->user_allow && !sw_context->kernel)) 2087c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_privileged; 2088c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom 2089c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom if (unlikely(entry->gb_disable && gb)) 2090c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_old; 2091c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom 2092c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom if (unlikely(entry->gb_enable && !gb)) 2093c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_new; 2094fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2095c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom ret = entry->func(dev_priv, sw_context, header); 2096fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2097c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom goto out_invalid; 2098fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2099fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 2100c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstromout_invalid: 2101c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom DRM_ERROR("Invalid SVGA3D command: %d\n", 2102c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom cmd_id + SVGA_3D_CMD_BASE); 2103c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom return -EINVAL; 2104c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstromout_privileged: 2105c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom DRM_ERROR("Privileged SVGA3D command: %d\n", 2106c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom cmd_id + SVGA_3D_CMD_BASE); 2107c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom return -EPERM; 2108c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstromout_old: 2109c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom DRM_ERROR("Deprecated (disallowed) SVGA3D command: %d\n", 2110c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom cmd_id + SVGA_3D_CMD_BASE); 2111c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom return -EINVAL; 2112c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstromout_new: 2113c373d4eac4a29b04ec036a0ead75e4a796c911c2Thomas Hellstrom DRM_ERROR("SVGA3D command: %d not supported by virtual hardware.\n", 2114fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cmd_id + SVGA_3D_CMD_BASE); 2115fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -EINVAL; 2116fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2117fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2118fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_cmd_check_all(struct vmw_private *dev_priv, 2119fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context, 2120922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom void *buf, 2121be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom uint32_t size) 2122fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2123fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int32_t cur_size = size; 2124fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 2125fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2126c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->buf_start = buf; 2127c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2128fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz while (cur_size > 0) { 21297a73ba7469cbea631050094fd14f73acebb97cf9Thomas Hellstrom size = cur_size; 2130fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = vmw_cmd_check(dev_priv, sw_context, buf, &size); 2131fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2132fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 2133fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz buf = (void *)((unsigned long) buf + size); 2134fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz cur_size -= size; 2135fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 2136fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2137fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(cur_size != 0)) { 2138fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Command verifier out of sync.\n"); 2139fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -EINVAL; 2140fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 2141fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2142fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 2143fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2144fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2145fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_free_relocations(struct vmw_sw_context *sw_context) 2146fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2147fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz sw_context->cur_reloc = 0; 2148fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2149fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2150fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_apply_relocations(struct vmw_sw_context *sw_context) 2151fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2152fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz uint32_t i; 2153fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_relocation *reloc; 2154fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct ttm_validate_buffer *validate; 2155fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct ttm_buffer_object *bo; 2156fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2157fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz for (i = 0; i < sw_context->cur_reloc; ++i) { 2158fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz reloc = &sw_context->relocs[i]; 2159c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom validate = &sw_context->val_bufs[reloc->index].base; 2160fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz bo = validate->bo; 2161c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom switch (bo->mem.mem_type) { 2162c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom case TTM_PL_VRAM: 2163135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom reloc->location->offset += bo->offset; 2164135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER; 2165c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom break; 2166c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom case VMW_PL_GMR: 2167135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom reloc->location->gmrId = bo->mem.start; 2168c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom break; 2169ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom case VMW_PL_MOB: 2170ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom *reloc->mob_loc = bo->mem.start; 2171ddcda24e3bec1d4c8bcc37e85d1b1b37bf0fecacThomas Hellstrom break; 2172c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom default: 2173c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG(); 2174c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 2175fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 2176fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_free_relocations(sw_context); 2177fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2178fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2179c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 2180c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_resource_list_unrefererence - Free up a resource list and unreference 2181c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * all resources referenced by it. 2182c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2183c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @list: The resource list. 2184c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 2185c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromstatic void vmw_resource_list_unreference(struct list_head *list) 2186c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 2187c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *val, *val_next; 2188c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2189c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom /* 2190c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Drop references to resources held during command submission. 2191c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 2192c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2193c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry_safe(val, val_next, list, head) { 2194c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_del_init(&val->head); 2195c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_unreference(&val->res); 2196b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom if (unlikely(val->staged_bindings)) 2197b5c3b1a6bfaf71895d656162f29e979c5c904888Thomas Hellstrom kfree(val->staged_bindings); 2198c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom kfree(val); 2199c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 2200c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 2201c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2202fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_clear_validations(struct vmw_sw_context *sw_context) 2203fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2204c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_validate_buffer *entry, *next; 2205c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource_val_node *val; 2206fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2207be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom /* 2208be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom * Drop references to DMA buffers held during command submission. 2209be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom */ 2210fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz list_for_each_entry_safe(entry, next, &sw_context->validate_nodes, 2211c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom base.head) { 2212c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_del(&entry->base.head); 2213c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ttm_bo_unref(&entry->base.bo); 2214c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom (void) drm_ht_remove_item(&sw_context->res_ht, &entry->hash); 2215fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz sw_context->cur_val_buf--; 2216fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 2217fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz BUG_ON(sw_context->cur_val_buf != 0); 2218be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2219c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry(val, &sw_context->resource_list, head) 2220c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom (void) drm_ht_remove_item(&sw_context->res_ht, &val->hash); 2221fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2222fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2223fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_validate_single_buffer(struct vmw_private *dev_priv, 222496c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom struct ttm_buffer_object *bo, 222596c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom bool validate_as_mob) 2226fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2227fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 2228fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2229e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2230e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom /* 2231e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * Don't validate pinned buffers. 2232e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 2233e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2234e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (bo == dev_priv->pinned_bo || 2235e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom (bo == dev_priv->dummy_query_bo && 2236e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom dev_priv->dummy_query_bo_pinned)) 2237e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return 0; 2238e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 223996c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom if (validate_as_mob) 224096c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom return ttm_bo_validate(bo, &vmw_mob_placement, true, false); 224196c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom 22428ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom /** 2243135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom * Put BO in VRAM if there is space, otherwise as a GMR. 2244135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom * If there is no space in VRAM and GMR ids are all used up, 2245135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom * start evicting GMRs to make room. If the DMA buffer can't be 2246135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom * used as a GMR, this will return -ENOMEM. 22478ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom */ 22488ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom 224997a875cbdf89a4638eea57c2b456c7cc4e3e8b21Maarten Lankhorst ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, true, false); 22503d3a5b3290043618e8409f3fb68a63de6156fdd4Thomas Hellstrom if (likely(ret == 0 || ret == -ERESTARTSYS)) 2251fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 2252fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 22538ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom /** 22548ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom * If that failed, try VRAM again, this time evicting 22558ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom * previous contents. 22568ba5152a3acd5914cade42a1c8c9dc58ad8d1a89Thomas Hellstrom */ 2257fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2258135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom DRM_INFO("Falling through to VRAM.\n"); 225997a875cbdf89a4638eea57c2b456c7cc4e3e8b21Maarten Lankhorst ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false); 2260fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 2261fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2262fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2263fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_validate_buffers(struct vmw_private *dev_priv, 2264fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context) 2265fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2266c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_validate_buffer *entry; 2267fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 2268fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2269c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_for_each_entry(entry, &sw_context->validate_nodes, base.head) { 227096c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom ret = vmw_validate_single_buffer(dev_priv, entry->base.bo, 227196c5f0df22aaf1f20075bc6ad3bdd7656e49cf4dThomas Hellstrom entry->validate_as_mob); 2272fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2273fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 2274fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 2275fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 2276fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2277fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2278be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstromstatic int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context, 2279be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom uint32_t size) 2280be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom{ 2281be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (likely(sw_context->cmd_bounce_size >= size)) 2282be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom return 0; 2283be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2284be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (sw_context->cmd_bounce_size == 0) 2285be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE; 2286be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2287be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom while (sw_context->cmd_bounce_size < size) { 2288be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom sw_context->cmd_bounce_size = 2289be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom PAGE_ALIGN(sw_context->cmd_bounce_size + 2290be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom (sw_context->cmd_bounce_size >> 1)); 2291be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom } 2292be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2293be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (sw_context->cmd_bounce != NULL) 2294be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom vfree(sw_context->cmd_bounce); 2295be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2296be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size); 2297be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2298be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (sw_context->cmd_bounce == NULL) { 2299be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom DRM_ERROR("Failed to allocate command bounce buffer.\n"); 2300be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom sw_context->cmd_bounce_size = 0; 2301be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom return -ENOMEM; 2302be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom } 2303be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2304be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom return 0; 2305be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom} 2306be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2307ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom/** 2308ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * vmw_execbuf_fence_commands - create and submit a command stream fence 2309ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * 2310ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * Creates a fence object and submits a command stream marker. 2311ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * If this fails for some reason, We sync the fifo and return NULL. 2312ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * It is then safe to fence buffers with a NULL pointer. 23136070e9fa6d12d465c65a172a2b1c752ebedc5937Jakob Bornecrantz * 23146070e9fa6d12d465c65a172a2b1c752ebedc5937Jakob Bornecrantz * If @p_handle is not NULL @file_priv must also not be NULL. Creates 23156070e9fa6d12d465c65a172a2b1c752ebedc5937Jakob Bornecrantz * a userspace handle if @p_handle is not NULL, otherwise not. 2316ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom */ 2317ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 2318ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstromint vmw_execbuf_fence_commands(struct drm_file *file_priv, 2319ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom struct vmw_private *dev_priv, 2320ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom struct vmw_fence_obj **p_fence, 2321ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom uint32_t *p_handle) 2322ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom{ 2323ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom uint32_t sequence; 2324ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom int ret; 2325ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom bool synced = false; 2326ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 23276070e9fa6d12d465c65a172a2b1c752ebedc5937Jakob Bornecrantz /* p_handle implies file_priv. */ 23286070e9fa6d12d465c65a172a2b1c752ebedc5937Jakob Bornecrantz BUG_ON(p_handle != NULL && file_priv == NULL); 2329ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 2330ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom ret = vmw_fifo_send_fence(dev_priv, &sequence); 2331ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom if (unlikely(ret != 0)) { 2332ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_ERROR("Fence submission error. Syncing.\n"); 2333ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom synced = true; 2334ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom } 2335ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 2336ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom if (p_handle != NULL) 2337ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom ret = vmw_user_fence_create(file_priv, dev_priv->fman, 2338c060a4e135fdd8a35276f2e318f1e9b3bc2450a9Maarten Lankhorst sequence, p_fence, p_handle); 2339ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom else 2340c060a4e135fdd8a35276f2e318f1e9b3bc2450a9Maarten Lankhorst ret = vmw_fence_create(dev_priv->fman, sequence, p_fence); 2341ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 2342ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom if (unlikely(ret != 0 && !synced)) { 2343ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom (void) vmw_fallback_wait(dev_priv, false, false, 2344ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom sequence, false, 2345ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom VMW_FENCE_WAIT_TIMEOUT); 2346ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom *p_fence = NULL; 2347ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom } 2348ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 2349ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom return 0; 2350ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom} 2351ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 23528bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom/** 23538bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * vmw_execbuf_copy_fence_user - copy fence object information to 23548bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * user-space. 23558bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * 23568bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @dev_priv: Pointer to a vmw_private struct. 23578bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file. 23588bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @ret: Return value from fence object creation. 23598bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to 23608bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * which the information should be copied. 23618bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @fence: Pointer to the fenc object. 23628bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * @fence_handle: User-space fence handle. 23638bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * 23648bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * This function copies fence information to user-space. If copying fails, 23658bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * The user-space struct drm_vmw_fence_rep::error member is hopefully 23668bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * left untouched, and if it's preloaded with an -EFAULT by user-space, 23678bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * the error will hopefully be detected. 23688bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * Also if copying fails, user-space will be unable to signal the fence 23698bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * object so we wait for it immediately, and then unreference the 23708bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * user-space reference. 23718bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom */ 237257c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstromvoid 23738bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstromvmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, 23748bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom struct vmw_fpriv *vmw_fp, 23758bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom int ret, 23768bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom struct drm_vmw_fence_rep __user *user_fence_rep, 23778bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom struct vmw_fence_obj *fence, 23788bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom uint32_t fence_handle) 23798bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom{ 23808bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom struct drm_vmw_fence_rep fence_rep; 23818bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 23828bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom if (user_fence_rep == NULL) 23838bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom return; 23848bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 238580d9b24a658c83602aea66e45e2347c5bb3cbd47Dan Carpenter memset(&fence_rep, 0, sizeof(fence_rep)); 238680d9b24a658c83602aea66e45e2347c5bb3cbd47Dan Carpenter 23878bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom fence_rep.error = ret; 23888bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom if (ret == 0) { 23898bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom BUG_ON(fence == NULL); 23908bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 23918bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom fence_rep.handle = fence_handle; 23922298e804e96eb3635c39519c8287befd92460303Maarten Lankhorst fence_rep.seqno = fence->base.seqno; 23938bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom vmw_update_seqno(dev_priv, &dev_priv->fifo); 23948bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom fence_rep.passed_seqno = dev_priv->last_read_seqno; 23958bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom } 23968bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 23978bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom /* 23988bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * copy_to_user errors will be detected by user space not 23998bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * seeing fence_rep::error filled in. Typically 24008bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * user-space would have pre-set that member to -EFAULT. 24018bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom */ 24028bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom ret = copy_to_user(user_fence_rep, &fence_rep, 24038bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom sizeof(fence_rep)); 24048bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 24058bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom /* 24068bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * User-space lost the fence object. We need to sync 24078bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom * and unreference the handle. 24088bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom */ 24098bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom if (unlikely(ret != 0) && (fence_rep.error == 0)) { 24108bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom ttm_ref_object_base_unref(vmw_fp->tfile, 24118bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom fence_handle, TTM_REF_USAGE); 24128bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom DRM_ERROR("Fence copy error. Syncing.\n"); 2413c060a4e135fdd8a35276f2e318f1e9b3bc2450a9Maarten Lankhorst (void) vmw_fence_obj_wait(fence, false, false, 24148bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom VMW_FENCE_WAIT_TIMEOUT); 24158bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom } 24168bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom} 24178bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom 241818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 241918e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom 2420922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstromint vmw_execbuf_process(struct drm_file *file_priv, 2421922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom struct vmw_private *dev_priv, 2422922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom void __user *user_commands, 2423922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom void *kernel_commands, 2424922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom uint32_t command_size, 2425922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom uint64_t throttle_us, 2426bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz struct drm_vmw_fence_rep __user *user_fence_rep, 2427bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz struct vmw_fence_obj **out_fence) 2428fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 2429fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_sw_context *sw_context = &dev_priv->ctx; 2430bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz struct vmw_fence_obj *fence = NULL; 2431c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_resource *error_resource; 2432c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct list_head resource_list; 2433ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst struct ww_acquire_ctx ticket; 2434ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom uint32_t handle; 2435922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom void *cmd; 2436922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom int ret; 2437fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2438922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex); 2439fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2440922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom return -ERESTARTSYS; 2441fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2442922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (kernel_commands == NULL) { 2443922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom sw_context->kernel = false; 2444fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2445922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = vmw_resize_cmd_bounce(sw_context, command_size); 2446922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (unlikely(ret != 0)) 2447922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom goto out_unlock; 2448fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2449fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2450922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = copy_from_user(sw_context->cmd_bounce, 2451922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom user_commands, command_size); 2452922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2453922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (unlikely(ret != 0)) { 2454922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = -EFAULT; 2455922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom DRM_ERROR("Failed copying commands.\n"); 2456922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom goto out_unlock; 2457922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom } 2458922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom kernel_commands = sw_context->cmd_bounce; 2459922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom } else 2460922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom sw_context->kernel = true; 2461fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2462d5bde956630b86462ee22055f5816a04290aed57Thomas Hellstrom sw_context->fp = vmw_fpriv(file_priv); 2463fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz sw_context->cur_reloc = 0; 2464fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz sw_context->cur_val_buf = 0; 2465f18c8840bef4195e6f35298b7746563f10d2d502Thomas Hellstrom INIT_LIST_HEAD(&sw_context->resource_list); 2466e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom sw_context->cur_query_bo = dev_priv->pinned_bo; 2467c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->last_query_ctx = NULL; 2468c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->needs_post_query_barrier = false; 2469c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache)); 2470fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz INIT_LIST_HEAD(&sw_context->validate_nodes); 2471c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom INIT_LIST_HEAD(&sw_context->res_relocations); 2472c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (!sw_context->res_ht_initialized) { 2473c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = drm_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER); 2474c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 2475c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_unlock; 2476c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->res_ht_initialized = true; 2477c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 247818e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom INIT_LIST_HEAD(&sw_context->staged_cmd_res); 2479fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2480c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom INIT_LIST_HEAD(&resource_list); 2481922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, 2482922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom command_size); 2483fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2484cf5e3413337309050c05e13dcebe85b7194a21e5Thomas Hellstrom goto out_err_nores; 2485be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2486c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_resources_reserve(sw_context); 2487c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 2488cf5e3413337309050c05e13dcebe85b7194a21e5Thomas Hellstrom goto out_err_nores; 2489c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 249058b4d720c1620bbf09e42b4f218dcb2d0d8cdf3eMaarten Lankhorst ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes, true); 2491fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2492fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err; 2493fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2494fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = vmw_validate_buffers(dev_priv, sw_context); 2495fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 2496fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err; 2497fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2498c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_resources_validate(sw_context); 2499c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) 2500c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_err; 25011925d4565888eb313cc923372da6a08bbfb3a859Thomas Hellstrom 2502922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (throttle_us) { 25036bcd8d3c782b7b2c98c8f414a6bb43cf6b84e53cThomas Hellstrom ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue, 2504922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom throttle_us); 25051925d4565888eb313cc923372da6a08bbfb3a859Thomas Hellstrom 25061925d4565888eb313cc923372da6a08bbfb3a859Thomas Hellstrom if (unlikely(ret != 0)) 2507c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_err; 2508be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom } 2509be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom 2510173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom ret = mutex_lock_interruptible(&dev_priv->binding_mutex); 2511173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom if (unlikely(ret != 0)) { 2512173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom ret = -ERESTARTSYS; 2513173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom goto out_err; 2514173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom } 2515173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom 251630f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (dev_priv->has_mob) { 251730f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom ret = vmw_rebind_contexts(sw_context); 251830f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom if (unlikely(ret != 0)) 2519b2ad9881d6aeec4f3ee527c00fce34442d6d02d3Dan Carpenter goto out_unlock_binding; 252030f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom } 252130f82d816d2dccfdc2063ac8cca994904c9b612cThomas Hellstrom 2522922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom cmd = vmw_fifo_reserve(dev_priv, command_size); 2523be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (unlikely(cmd == NULL)) { 2524be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom DRM_ERROR("Failed reserving fifo space for commands.\n"); 2525be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom ret = -ENOMEM; 2526173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom goto out_unlock_binding; 25271925d4565888eb313cc923372da6a08bbfb3a859Thomas Hellstrom } 25281925d4565888eb313cc923372da6a08bbfb3a859Thomas Hellstrom 2529c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_apply_relocations(sw_context); 2530922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom memcpy(cmd, kernel_commands, command_size); 2531c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2532c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_relocations_apply(cmd, &sw_context->res_relocations); 2533c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_relocations_free(&sw_context->res_relocations); 2534c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2535922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom vmw_fifo_commit(dev_priv, command_size); 2536fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2537e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_query_bo_switch_commit(dev_priv, sw_context); 2538ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom ret = vmw_execbuf_fence_commands(file_priv, dev_priv, 2539ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom &fence, 2540ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom (user_fence_rep) ? &handle : NULL); 2541fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz /* 2542fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * This error is harmless, because if fence submission fails, 2543ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * vmw_fifo_send_fence will sync. The error will be propagated to 2544ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom * user-space in @fence_rep 2545fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 2546fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2547fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (ret != 0) 2548fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Fence submission error. Syncing.\n"); 2549fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2550c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_list_unreserve(&sw_context->resource_list, false); 2551173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom mutex_unlock(&dev_priv->binding_mutex); 2552173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom 2553ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes, 2554ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom (void *) fence); 2555fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2556c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(dev_priv->pinned_bo != NULL && 2557c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom !dev_priv->query_cid_valid)) 2558c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom __vmw_execbuf_release_pinned_bo(dev_priv, fence); 2559c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2560ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_clear_validations(sw_context); 25618bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, 25628bf445cee3127de3779a395d08d1ada2ad70161eThomas Hellstrom user_fence_rep, fence, handle); 2563fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2564bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz /* Don't unreference when handing fence out */ 2565bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz if (unlikely(out_fence != NULL)) { 2566bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz *out_fence = fence; 2567bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz fence = NULL; 2568bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz } else if (likely(fence != NULL)) { 2569ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_obj_unreference(&fence); 2570bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz } 2571fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 2572c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_splice_init(&sw_context->resource_list, &resource_list); 257318e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_cmdbuf_res_commit(&sw_context->staged_cmd_res); 2574922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom mutex_unlock(&dev_priv->cmdbuf_mutex); 2575c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2576c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom /* 2577c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Unreference resources outside of the cmdbuf_mutex to 2578c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * avoid deadlocks in resource destruction paths. 2579c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 2580c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_list_unreference(&resource_list); 2581c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2582fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 2583922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2584173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstromout_unlock_binding: 2585173fb7d4e26705a9e8b8e9d197a18ff39bfdad0aThomas Hellstrom mutex_unlock(&dev_priv->binding_mutex); 2586fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err: 2587ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes); 2588cf5e3413337309050c05e13dcebe85b7194a21e5Thomas Hellstromout_err_nores: 2589c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_list_unreserve(&sw_context->resource_list, true); 2590cf5e3413337309050c05e13dcebe85b7194a21e5Thomas Hellstrom vmw_resource_relocations_free(&sw_context->res_relocations); 2591cf5e3413337309050c05e13dcebe85b7194a21e5Thomas Hellstrom vmw_free_relocations(sw_context); 2592fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_clear_validations(sw_context); 2593c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(dev_priv->pinned_bo != NULL && 2594c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom !dev_priv->query_cid_valid)) 2595c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom __vmw_execbuf_release_pinned_bo(dev_priv, NULL); 2596fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_unlock: 2597c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom list_splice_init(&sw_context->resource_list, &resource_list); 2598c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom error_resource = sw_context->error_resource; 2599c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom sw_context->error_resource = NULL; 260018e4a4669c5023eb1157f2a3f1bf6ca2b8535572Thomas Hellstrom vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res); 2601fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_unlock(&dev_priv->cmdbuf_mutex); 2602c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2603c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom /* 2604c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * Unreference resources outside of the cmdbuf_mutex to 2605c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * avoid deadlocks in resource destruction paths. 2606c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 2607c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_list_unreference(&resource_list); 2608c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(error_resource != NULL)) 2609c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_resource_unreference(&error_resource); 2610c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2611922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom return ret; 2612922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom} 2613922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2614e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 2615e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer. 2616e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2617e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: The device private structure. 2618e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2619e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function is called to idle the fifo and unpin the query buffer 2620e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * if the normal way to do this hits an error, which should typically be 2621e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * extremely rare. 2622e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 2623e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv) 2624e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 2625e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom DRM_ERROR("Can't unpin query buffer. Trying to recover.\n"); 2626e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2627e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ); 2628e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_bo_pin(dev_priv->pinned_bo, false); 2629e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_bo_pin(dev_priv->dummy_query_bo, false); 2630e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom dev_priv->dummy_query_bo_pinned = false; 2631e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 2632e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2633e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2634e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 2635c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned 2636e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * query bo. 2637e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2638e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: The device private structure. 2639c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @fence: If non-NULL should point to a struct vmw_fence_obj issued 2640c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * _after_ a query barrier that flushes all queries touching the current 2641c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * buffer pointed to by @dev_priv->pinned_bo 2642e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2643e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function should be used to unpin the pinned query bo, or 2644e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * as a query barrier when we need to make sure that all queries have 2645e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * finished before the next fifo command. (For example on hardware 2646e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * context destructions where the hardware may otherwise leak unfinished 2647e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * queries). 2648e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2649e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function does not return any failure codes, but make attempts 2650e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * to do safe unpinning in case of errors. 2651e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 2652e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * The function will synchronize on the previous query barrier, and will 2653e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * thus not finish until that barrier has executed. 2654c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2655c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * the @dev_priv->cmdbuf_mutex needs to be held by the current thread 2656c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * before calling this function. 2657e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 2658c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromvoid __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, 2659c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_fence_obj *fence) 2660e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 2661e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom int ret = 0; 2662e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct list_head validate_list; 2663e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_validate_buffer pinned_val, query_val; 2664c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom struct vmw_fence_obj *lfence = NULL; 2665ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst struct ww_acquire_ctx ticket; 2666e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2667e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (dev_priv->pinned_bo == NULL) 2668e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom goto out_unlock; 2669e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2670e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom INIT_LIST_HEAD(&validate_list); 2671e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2672e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo); 2673ae9c0af2c0ea92e57013ab2dd7271ba7d6b2a833Christian König pinned_val.shared = false; 2674e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom list_add_tail(&pinned_val.head, &validate_list); 2675e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2676e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo); 2677ae9c0af2c0ea92e57013ab2dd7271ba7d6b2a833Christian König query_val.shared = false; 2678e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom list_add_tail(&query_val.head, &validate_list); 2679e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 268058b4d720c1620bbf09e42b4f218dcb2d0d8cdf3eMaarten Lankhorst ret = ttm_eu_reserve_buffers(&ticket, &validate_list, false); 2681e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) { 2682e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_execbuf_unpin_panic(dev_priv); 2683e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom goto out_no_reserve; 2684e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 2685e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2686c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (dev_priv->query_cid_valid) { 2687c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom BUG_ON(fence != NULL); 2688c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom ret = vmw_fifo_emit_dummy_query(dev_priv, dev_priv->query_cid); 2689c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (unlikely(ret != 0)) { 2690c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_execbuf_unpin_panic(dev_priv); 2691c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom goto out_no_emit; 2692c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 2693c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom dev_priv->query_cid_valid = false; 2694e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } 2695e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2696e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_bo_pin(dev_priv->pinned_bo, false); 2697e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_bo_pin(dev_priv->dummy_query_bo, false); 2698e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom dev_priv->dummy_query_bo_pinned = false; 2699e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2700c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (fence == NULL) { 2701c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom (void) vmw_execbuf_fence_commands(NULL, dev_priv, &lfence, 2702c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom NULL); 2703c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom fence = lfence; 2704c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom } 2705ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst ttm_eu_fence_buffer_objects(&ticket, &validate_list, (void *) fence); 2706c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (lfence != NULL) 2707c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom vmw_fence_obj_unreference(&lfence); 2708e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2709e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&query_val.bo); 2710e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&pinned_val.bo); 2711e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&dev_priv->pinned_bo); 2712e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2713e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromout_unlock: 2714e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return; 2715e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2716e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromout_no_emit: 2717ecff665f5e3f1c6909353e00b9420e45ae23d995Maarten Lankhorst ttm_eu_backoff_reservation(&ticket, &validate_list); 2718e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromout_no_reserve: 2719e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&query_val.bo); 2720e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&pinned_val.bo); 2721e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&dev_priv->pinned_bo); 2722c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom} 2723c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom 2724c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom/** 2725c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned 2726c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * query bo. 2727c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2728c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * @dev_priv: The device private structure. 2729c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2730c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * This function should be used to unpin the pinned query bo, or 2731c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * as a query barrier when we need to make sure that all queries have 2732c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * finished before the next fifo command. (For example on hardware 2733c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * context destructions where the hardware may otherwise leak unfinished 2734c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * queries). 2735c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2736c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * This function does not return any failure codes, but make attempts 2737c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * to do safe unpinning in case of errors. 2738c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * 2739c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * The function will synchronize on the previous query barrier, and will 2740c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom * thus not finish until that barrier has executed. 2741c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom */ 2742c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstromvoid vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv) 2743c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom{ 2744c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom mutex_lock(&dev_priv->cmdbuf_mutex); 2745c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom if (dev_priv->query_cid_valid) 2746c0951b797e7d0f2c6b0df2c0e18185c72d0cf1a1Thomas Hellstrom __vmw_execbuf_release_pinned_bo(dev_priv, NULL); 2747e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom mutex_unlock(&dev_priv->cmdbuf_mutex); 2748e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 2749e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 2750922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2751922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstromint vmw_execbuf_ioctl(struct drm_device *dev, void *data, 2752922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom struct drm_file *file_priv) 2753922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom{ 2754922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom struct vmw_private *dev_priv = vmw_priv(dev); 2755922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data; 2756922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom int ret; 2757922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2758922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom /* 2759922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom * This will allow us to extend the ioctl argument while 2760922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom * maintaining backwards compatibility: 2761922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom * We take different code paths depending on the value of 2762922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom * arg->version. 2763922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom */ 2764922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2765922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (unlikely(arg->version != DRM_VMW_EXECBUF_VERSION)) { 2766922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom DRM_ERROR("Incorrect execbuf version.\n"); 2767922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom DRM_ERROR("You're running outdated experimental " 2768922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom "vmwgfx user-space drivers."); 2769922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom return -EINVAL; 2770922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom } 2771922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2772294adf7d86226c0e6abeb4475159b03aa315d56fThomas Hellstrom ret = ttm_read_lock(&dev_priv->reservation_sem, true); 2773922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (unlikely(ret != 0)) 2774922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom return ret; 2775922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2776922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom ret = vmw_execbuf_process(file_priv, dev_priv, 2777922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom (void __user *)(unsigned long)arg->commands, 2778922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom NULL, arg->command_size, arg->throttle_us, 2779bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz (void __user *)(unsigned long)arg->fence_rep, 2780bb1bd2f43ee15386a1c3f96cbcbb9302a9994443Jakob Bornecrantz NULL); 2781922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2782922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom if (unlikely(ret != 0)) 2783922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom goto out_unlock; 2784922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2785922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom vmw_kms_cursor_post_execbuf(dev_priv); 2786922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstrom 2787922ade0d16d24be2040be7d55dbb734af779a1ddThomas Hellstromout_unlock: 2788294adf7d86226c0e6abeb4475159b03aa315d56fThomas Hellstrom ttm_read_unlock(&dev_priv->reservation_sem); 2789fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 2790fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 2791