Subversion Repositories Kolibri OS

Rev

Rev 4111 | Rev 5078 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4111 Rev 4569
1
/**************************************************************************
1
/**************************************************************************
2
 *
2
 *
3
 * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
3
 * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
4
 * All Rights Reserved.
4
 * All Rights Reserved.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
12
 * the following conditions:
13
 *
13
 *
14
 * The above copyright notice and this permission notice (including the
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
16
 * of the Software.
17
 *
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
25
 *
26
 **************************************************************************/
26
 **************************************************************************/
27
 
27
 
28
#include "vmwgfx_drv.h"
28
#include "vmwgfx_drv.h"
29
#include "vmwgfx_reg.h"
29
#include "vmwgfx_reg.h"
30
#include 
30
#include 
31
#include 
31
#include 
32
 
32
 
33
#define VMW_RES_HT_ORDER 12
33
#define VMW_RES_HT_ORDER 12
34
 
34
 
35
/**
35
/**
36
 * struct vmw_resource_relocation - Relocation info for resources
36
 * struct vmw_resource_relocation - Relocation info for resources
37
 *
37
 *
38
 * @head: List head for the software context's relocation list.
38
 * @head: List head for the software context's relocation list.
39
 * @res: Non-ref-counted pointer to the resource.
39
 * @res: Non-ref-counted pointer to the resource.
40
 * @offset: Offset of 4 byte entries into the command buffer where the
40
 * @offset: Offset of 4 byte entries into the command buffer where the
41
 * id that needs fixup is located.
41
 * id that needs fixup is located.
42
 */
42
 */
43
struct vmw_resource_relocation {
43
struct vmw_resource_relocation {
44
	struct list_head head;
44
	struct list_head head;
45
	const struct vmw_resource *res;
45
	const struct vmw_resource *res;
46
	unsigned long offset;
46
	unsigned long offset;
47
};
47
};
48
 
48
 
49
/**
49
/**
50
 * struct vmw_resource_val_node - Validation info for resources
50
 * struct vmw_resource_val_node - Validation info for resources
51
 *
51
 *
52
 * @head: List head for the software context's resource list.
52
 * @head: List head for the software context's resource list.
53
 * @hash: Hash entry for quick resouce to val_node lookup.
53
 * @hash: Hash entry for quick resouce to val_node lookup.
54
 * @res: Ref-counted pointer to the resource.
54
 * @res: Ref-counted pointer to the resource.
55
 * @switch_backup: Boolean whether to switch backup buffer on unreserve.
55
 * @switch_backup: Boolean whether to switch backup buffer on unreserve.
56
 * @new_backup: Refcounted pointer to the new backup buffer.
56
 * @new_backup: Refcounted pointer to the new backup buffer.
-
 
57
 * @staged_bindings: If @res is a context, tracks bindings set up during
-
 
58
 * the command batch. Otherwise NULL.
57
 * @new_backup_offset: New backup buffer offset if @new_backup is non-NUll.
59
 * @new_backup_offset: New backup buffer offset if @new_backup is non-NUll.
58
 * @first_usage: Set to true the first time the resource is referenced in
60
 * @first_usage: Set to true the first time the resource is referenced in
59
 * the command stream.
61
 * the command stream.
60
 * @no_buffer_needed: Resources do not need to allocate buffer backup on
62
 * @no_buffer_needed: Resources do not need to allocate buffer backup on
61
 * reservation. The command stream will provide one.
63
 * reservation. The command stream will provide one.
62
 */
64
 */
63
struct vmw_resource_val_node {
65
struct vmw_resource_val_node {
64
	struct list_head head;
66
	struct list_head head;
65
	struct drm_hash_item hash;
67
	struct drm_hash_item hash;
66
	struct vmw_resource *res;
68
	struct vmw_resource *res;
67
	struct vmw_dma_buffer *new_backup;
69
	struct vmw_dma_buffer *new_backup;
-
 
70
	struct vmw_ctx_binding_state *staged_bindings;
68
	unsigned long new_backup_offset;
71
	unsigned long new_backup_offset;
69
	bool first_usage;
72
	bool first_usage;
70
	bool no_buffer_needed;
73
	bool no_buffer_needed;
71
};
74
};
72
 
75
 
73
/**
76
/**
-
 
77
 * struct vmw_cmd_entry - Describe a command for the verifier
-
 
78
 *
-
 
79
 * @user_allow: Whether allowed from the execbuf ioctl.
-
 
80
 * @gb_disable: Whether disabled if guest-backed objects are available.
-
 
81
 * @gb_enable: Whether enabled iff guest-backed objects are available.
-
 
82
 */
-
 
83
struct vmw_cmd_entry {
-
 
84
	int (*func) (struct vmw_private *, struct vmw_sw_context *,
-
 
85
		     SVGA3dCmdHeader *);
-
 
86
	bool user_allow;
-
 
87
	bool gb_disable;
-
 
88
	bool gb_enable;
-
 
89
};
-
 
90
 
-
 
91
#define VMW_CMD_DEF(_cmd, _func, _user_allow, _gb_disable, _gb_enable)	\
-
 
92
	[(_cmd) - SVGA_3D_CMD_BASE] = {(_func), (_user_allow),\
-
 
93
				       (_gb_disable), (_gb_enable)}
-
 
94
 
-
 
95
/**
74
 * vmw_resource_unreserve - unreserve resources previously reserved for
96
 * vmw_resource_unreserve - unreserve resources previously reserved for
75
 * command submission.
97
 * command submission.
76
 *
98
 *
77
 * @list_head: list of resources to unreserve.
99
 * @list_head: list of resources to unreserve.
78
 * @backoff: Whether command submission failed.
100
 * @backoff: Whether command submission failed.
79
 */
101
 */
80
static void vmw_resource_list_unreserve(struct list_head *list,
102
static void vmw_resource_list_unreserve(struct list_head *list,
81
					bool backoff)
103
					bool backoff)
82
{
104
{
83
	struct vmw_resource_val_node *val;
105
	struct vmw_resource_val_node *val;
84
 
106
 
85
	list_for_each_entry(val, list, head) {
107
	list_for_each_entry(val, list, head) {
86
		struct vmw_resource *res = val->res;
108
		struct vmw_resource *res = val->res;
87
		struct vmw_dma_buffer *new_backup =
109
		struct vmw_dma_buffer *new_backup =
88
			backoff ? NULL : val->new_backup;
110
			backoff ? NULL : val->new_backup;
-
 
111
 
-
 
112
		/*
-
 
113
		 * Transfer staged context bindings to the
-
 
114
		 * persistent context binding tracker.
-
 
115
		 */
-
 
116
		if (unlikely(val->staged_bindings)) {
-
 
117
			vmw_context_binding_state_transfer
-
 
118
				(val->res, val->staged_bindings);
-
 
119
			kfree(val->staged_bindings);
-
 
120
			val->staged_bindings = NULL;
89
 
121
		}
90
		vmw_resource_unreserve(res, new_backup,
122
		vmw_resource_unreserve(res, new_backup,
91
			val->new_backup_offset);
123
			val->new_backup_offset);
92
		vmw_dmabuf_unreference(&val->new_backup);
124
		vmw_dmabuf_unreference(&val->new_backup);
93
	}
125
	}
94
}
126
}
95
 
127
 
96
 
128
 
97
/**
129
/**
98
 * vmw_resource_val_add - Add a resource to the software context's
130
 * vmw_resource_val_add - Add a resource to the software context's
99
 * resource list if it's not already on it.
131
 * resource list if it's not already on it.
100
 *
132
 *
101
 * @sw_context: Pointer to the software context.
133
 * @sw_context: Pointer to the software context.
102
 * @res: Pointer to the resource.
134
 * @res: Pointer to the resource.
103
 * @p_node On successful return points to a valid pointer to a
135
 * @p_node On successful return points to a valid pointer to a
104
 * struct vmw_resource_val_node, if non-NULL on entry.
136
 * struct vmw_resource_val_node, if non-NULL on entry.
105
 */
137
 */
106
static int vmw_resource_val_add(struct vmw_sw_context *sw_context,
138
static int vmw_resource_val_add(struct vmw_sw_context *sw_context,
107
				struct vmw_resource *res,
139
				struct vmw_resource *res,
108
				struct vmw_resource_val_node **p_node)
140
				struct vmw_resource_val_node **p_node)
109
{
141
{
110
	struct vmw_resource_val_node *node;
142
	struct vmw_resource_val_node *node;
111
	struct drm_hash_item *hash;
143
	struct drm_hash_item *hash;
112
	int ret;
144
	int ret;
113
 
145
 
114
	if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) res,
146
	if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) res,
115
				    &hash) == 0)) {
147
				    &hash) == 0)) {
116
		node = container_of(hash, struct vmw_resource_val_node, hash);
148
		node = container_of(hash, struct vmw_resource_val_node, hash);
117
		node->first_usage = false;
149
		node->first_usage = false;
118
		if (unlikely(p_node != NULL))
150
		if (unlikely(p_node != NULL))
119
			*p_node = node;
151
			*p_node = node;
120
		return 0;
152
		return 0;
121
	}
153
	}
122
 
154
 
123
	node = kzalloc(sizeof(*node), GFP_KERNEL);
155
	node = kzalloc(sizeof(*node), GFP_KERNEL);
124
	if (unlikely(node == NULL)) {
156
	if (unlikely(node == NULL)) {
125
		DRM_ERROR("Failed to allocate a resource validation "
157
		DRM_ERROR("Failed to allocate a resource validation "
126
			  "entry.\n");
158
			  "entry.\n");
127
		return -ENOMEM;
159
		return -ENOMEM;
128
	}
160
	}
129
 
161
 
130
	node->hash.key = (unsigned long) res;
162
	node->hash.key = (unsigned long) res;
131
	ret = drm_ht_insert_item(&sw_context->res_ht, &node->hash);
163
	ret = drm_ht_insert_item(&sw_context->res_ht, &node->hash);
132
	if (unlikely(ret != 0)) {
164
	if (unlikely(ret != 0)) {
133
		DRM_ERROR("Failed to initialize a resource validation "
165
		DRM_ERROR("Failed to initialize a resource validation "
134
			  "entry.\n");
166
			  "entry.\n");
135
		kfree(node);
167
		kfree(node);
136
		return ret;
168
		return ret;
137
	}
169
	}
138
	list_add_tail(&node->head, &sw_context->resource_list);
170
	list_add_tail(&node->head, &sw_context->resource_list);
139
	node->res = vmw_resource_reference(res);
171
	node->res = vmw_resource_reference(res);
140
	node->first_usage = true;
172
	node->first_usage = true;
141
 
173
 
142
	if (unlikely(p_node != NULL))
174
	if (unlikely(p_node != NULL))
143
		*p_node = node;
175
		*p_node = node;
144
 
176
 
145
	return 0;
177
	return 0;
146
}
178
}
147
 
179
 
148
/**
180
/**
149
 * vmw_resource_relocation_add - Add a relocation to the relocation list
181
 * vmw_resource_relocation_add - Add a relocation to the relocation list
150
 *
182
 *
151
 * @list: Pointer to head of relocation list.
183
 * @list: Pointer to head of relocation list.
152
 * @res: The resource.
184
 * @res: The resource.
153
 * @offset: Offset into the command buffer currently being parsed where the
185
 * @offset: Offset into the command buffer currently being parsed where the
154
 * id that needs fixup is located. Granularity is 4 bytes.
186
 * id that needs fixup is located. Granularity is 4 bytes.
155
 */
187
 */
156
static int vmw_resource_relocation_add(struct list_head *list,
188
static int vmw_resource_relocation_add(struct list_head *list,
157
				       const struct vmw_resource *res,
189
				       const struct vmw_resource *res,
158
				       unsigned long offset)
190
				       unsigned long offset)
159
{
191
{
160
	struct vmw_resource_relocation *rel;
192
	struct vmw_resource_relocation *rel;
161
 
193
 
162
	rel = kmalloc(sizeof(*rel), GFP_KERNEL);
194
	rel = kmalloc(sizeof(*rel), GFP_KERNEL);
163
	if (unlikely(rel == NULL)) {
195
	if (unlikely(rel == NULL)) {
164
		DRM_ERROR("Failed to allocate a resource relocation.\n");
196
		DRM_ERROR("Failed to allocate a resource relocation.\n");
165
		return -ENOMEM;
197
		return -ENOMEM;
166
	}
198
	}
167
 
199
 
168
	rel->res = res;
200
	rel->res = res;
169
	rel->offset = offset;
201
	rel->offset = offset;
170
	list_add_tail(&rel->head, list);
202
	list_add_tail(&rel->head, list);
171
 
203
 
172
	return 0;
204
	return 0;
173
}
205
}
174
 
206
 
175
/**
207
/**
176
 * vmw_resource_relocations_free - Free all relocations on a list
208
 * vmw_resource_relocations_free - Free all relocations on a list
177
 *
209
 *
178
 * @list: Pointer to the head of the relocation list.
210
 * @list: Pointer to the head of the relocation list.
179
 */
211
 */
180
static void vmw_resource_relocations_free(struct list_head *list)
212
static void vmw_resource_relocations_free(struct list_head *list)
181
{
213
{
182
	struct vmw_resource_relocation *rel, *n;
214
	struct vmw_resource_relocation *rel, *n;
183
 
215
 
184
	list_for_each_entry_safe(rel, n, list, head) {
216
	list_for_each_entry_safe(rel, n, list, head) {
185
		list_del(&rel->head);
217
		list_del(&rel->head);
186
		kfree(rel);
218
		kfree(rel);
187
	}
219
	}
188
}
220
}
189
 
221
 
190
/**
222
/**
191
 * vmw_resource_relocations_apply - Apply all relocations on a list
223
 * vmw_resource_relocations_apply - Apply all relocations on a list
192
 *
224
 *
193
 * @cb: Pointer to the start of the command buffer bein patch. This need
225
 * @cb: Pointer to the start of the command buffer bein patch. This need
194
 * not be the same buffer as the one being parsed when the relocation
226
 * not be the same buffer as the one being parsed when the relocation
195
 * list was built, but the contents must be the same modulo the
227
 * list was built, but the contents must be the same modulo the
196
 * resource ids.
228
 * resource ids.
197
 * @list: Pointer to the head of the relocation list.
229
 * @list: Pointer to the head of the relocation list.
198
 */
230
 */
199
static void vmw_resource_relocations_apply(uint32_t *cb,
231
static void vmw_resource_relocations_apply(uint32_t *cb,
200
					   struct list_head *list)
232
					   struct list_head *list)
201
{
233
{
202
	struct vmw_resource_relocation *rel;
234
	struct vmw_resource_relocation *rel;
203
 
235
 
204
	list_for_each_entry(rel, list, head)
236
	list_for_each_entry(rel, list, head)
205
		cb[rel->offset] = rel->res->id;
237
		cb[rel->offset] = rel->res->id;
206
}
238
}
207
 
239
 
208
static int vmw_cmd_invalid(struct vmw_private *dev_priv,
240
static int vmw_cmd_invalid(struct vmw_private *dev_priv,
209
			   struct vmw_sw_context *sw_context,
241
			   struct vmw_sw_context *sw_context,
210
			   SVGA3dCmdHeader *header)
242
			   SVGA3dCmdHeader *header)
211
{
243
{
212
    return 0; //capable(CAP_SYS_ADMIN) ? : -EINVAL;
244
    return 0; //capable(CAP_SYS_ADMIN) ? : -EINVAL;
213
}
245
}
214
 
246
 
215
static int vmw_cmd_ok(struct vmw_private *dev_priv,
247
static int vmw_cmd_ok(struct vmw_private *dev_priv,
216
		      struct vmw_sw_context *sw_context,
248
		      struct vmw_sw_context *sw_context,
217
		      SVGA3dCmdHeader *header)
249
		      SVGA3dCmdHeader *header)
218
{
250
{
219
	return 0;
251
	return 0;
220
}
252
}
221
 
253
 
222
/**
254
/**
223
 * vmw_bo_to_validate_list - add a bo to a validate list
255
 * vmw_bo_to_validate_list - add a bo to a validate list
224
 *
256
 *
225
 * @sw_context: The software context used for this command submission batch.
257
 * @sw_context: The software context used for this command submission batch.
226
 * @bo: The buffer object to add.
258
 * @bo: The buffer object to add.
-
 
259
 * @validate_as_mob: Validate this buffer as a MOB.
227
 * @p_val_node: If non-NULL Will be updated with the validate node number
260
 * @p_val_node: If non-NULL Will be updated with the validate node number
228
 * on return.
261
 * on return.
229
 *
262
 *
230
 * Returns -EINVAL if the limit of number of buffer objects per command
263
 * Returns -EINVAL if the limit of number of buffer objects per command
231
 * submission is reached.
264
 * submission is reached.
232
 */
265
 */
233
static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
266
static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
234
				   struct ttm_buffer_object *bo,
267
				   struct ttm_buffer_object *bo,
-
 
268
				   bool validate_as_mob,
235
				   uint32_t *p_val_node)
269
				   uint32_t *p_val_node)
236
{
270
{
237
	uint32_t val_node;
271
	uint32_t val_node;
238
	struct vmw_validate_buffer *vval_buf;
272
	struct vmw_validate_buffer *vval_buf;
239
	struct ttm_validate_buffer *val_buf;
273
	struct ttm_validate_buffer *val_buf;
240
	struct drm_hash_item *hash;
274
	struct drm_hash_item *hash;
241
	int ret;
275
	int ret;
242
 
276
 
243
	if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) bo,
277
	if (likely(drm_ht_find_item(&sw_context->res_ht, (unsigned long) bo,
244
				    &hash) == 0)) {
278
				    &hash) == 0)) {
245
		vval_buf = container_of(hash, struct vmw_validate_buffer,
279
		vval_buf = container_of(hash, struct vmw_validate_buffer,
246
					hash);
280
					hash);
-
 
281
		if (unlikely(vval_buf->validate_as_mob != validate_as_mob)) {
-
 
282
			DRM_ERROR("Inconsistent buffer usage.\n");
-
 
283
			return -EINVAL;
-
 
284
		}
247
		val_buf = &vval_buf->base;
285
		val_buf = &vval_buf->base;
248
		val_node = vval_buf - sw_context->val_bufs;
286
		val_node = vval_buf - sw_context->val_bufs;
249
	} else {
287
	} else {
250
		val_node = sw_context->cur_val_buf;
288
		val_node = sw_context->cur_val_buf;
251
		if (unlikely(val_node >= VMWGFX_MAX_VALIDATIONS)) {
289
		if (unlikely(val_node >= VMWGFX_MAX_VALIDATIONS)) {
252
			DRM_ERROR("Max number of DMA buffers per submission "
290
			DRM_ERROR("Max number of DMA buffers per submission "
253
				  "exceeded.\n");
291
				  "exceeded.\n");
254
			return -EINVAL;
292
			return -EINVAL;
255
		}
293
		}
256
		vval_buf = &sw_context->val_bufs[val_node];
294
		vval_buf = &sw_context->val_bufs[val_node];
257
		vval_buf->hash.key = (unsigned long) bo;
295
		vval_buf->hash.key = (unsigned long) bo;
258
		ret = drm_ht_insert_item(&sw_context->res_ht, &vval_buf->hash);
296
		ret = drm_ht_insert_item(&sw_context->res_ht, &vval_buf->hash);
259
		if (unlikely(ret != 0)) {
297
		if (unlikely(ret != 0)) {
260
			DRM_ERROR("Failed to initialize a buffer validation "
298
			DRM_ERROR("Failed to initialize a buffer validation "
261
				  "entry.\n");
299
				  "entry.\n");
262
			return ret;
300
			return ret;
263
		}
301
		}
264
		++sw_context->cur_val_buf;
302
		++sw_context->cur_val_buf;
265
		val_buf = &vval_buf->base;
303
		val_buf = &vval_buf->base;
266
		val_buf->bo = ttm_bo_reference(bo);
304
		val_buf->bo = ttm_bo_reference(bo);
267
		val_buf->reserved = false;
305
		val_buf->reserved = false;
268
		list_add_tail(&val_buf->head, &sw_context->validate_nodes);
306
		list_add_tail(&val_buf->head, &sw_context->validate_nodes);
-
 
307
		vval_buf->validate_as_mob = validate_as_mob;
269
	}
308
	}
270
 
309
 
271
	sw_context->fence_flags |= DRM_VMW_FENCE_FLAG_EXEC;
310
	sw_context->fence_flags |= DRM_VMW_FENCE_FLAG_EXEC;
272
 
311
 
273
	if (p_val_node)
312
	if (p_val_node)
274
		*p_val_node = val_node;
313
		*p_val_node = val_node;
275
 
314
 
276
	return 0;
315
	return 0;
277
}
316
}
278
 
317
 
279
/**
318
/**
280
 * vmw_resources_reserve - Reserve all resources on the sw_context's
319
 * vmw_resources_reserve - Reserve all resources on the sw_context's
281
 * resource list.
320
 * resource list.
282
 *
321
 *
283
 * @sw_context: Pointer to the software context.
322
 * @sw_context: Pointer to the software context.
284
 *
323
 *
285
 * Note that since vmware's command submission currently is protected by
324
 * Note that since vmware's command submission currently is protected by
286
 * the cmdbuf mutex, no fancy deadlock avoidance is required for resources,
325
 * the cmdbuf mutex, no fancy deadlock avoidance is required for resources,
287
 * since only a single thread at once will attempt this.
326
 * since only a single thread at once will attempt this.
288
 */
327
 */
289
static int vmw_resources_reserve(struct vmw_sw_context *sw_context)
328
static int vmw_resources_reserve(struct vmw_sw_context *sw_context)
290
{
329
{
291
	struct vmw_resource_val_node *val;
330
	struct vmw_resource_val_node *val;
292
	int ret;
331
	int ret;
293
 
332
 
294
	list_for_each_entry(val, &sw_context->resource_list, head) {
333
	list_for_each_entry(val, &sw_context->resource_list, head) {
295
		struct vmw_resource *res = val->res;
334
		struct vmw_resource *res = val->res;
296
 
335
 
297
		ret = vmw_resource_reserve(res, val->no_buffer_needed);
336
		ret = vmw_resource_reserve(res, val->no_buffer_needed);
298
		if (unlikely(ret != 0))
337
		if (unlikely(ret != 0))
299
			return ret;
338
			return ret;
300
 
339
 
301
		if (res->backup) {
340
		if (res->backup) {
302
			struct ttm_buffer_object *bo = &res->backup->base;
341
			struct ttm_buffer_object *bo = &res->backup->base;
303
 
342
 
304
			ret = vmw_bo_to_validate_list
343
			ret = vmw_bo_to_validate_list
305
				(sw_context, bo, NULL);
344
				(sw_context, bo,
-
 
345
				 vmw_resource_needs_backup(res), NULL);
306
 
346
 
307
			if (unlikely(ret != 0))
347
			if (unlikely(ret != 0))
308
				return ret;
348
				return ret;
309
		}
349
		}
310
	}
350
	}
311
	return 0;
351
	return 0;
312
}
352
}
313
 
353
 
314
/**
354
/**
315
 * vmw_resources_validate - Validate all resources on the sw_context's
355
 * vmw_resources_validate - Validate all resources on the sw_context's
316
 * resource list.
356
 * resource list.
317
 *
357
 *
318
 * @sw_context: Pointer to the software context.
358
 * @sw_context: Pointer to the software context.
319
 *
359
 *
320
 * Before this function is called, all resource backup buffers must have
360
 * Before this function is called, all resource backup buffers must have
321
 * been validated.
361
 * been validated.
322
 */
362
 */
323
static int vmw_resources_validate(struct vmw_sw_context *sw_context)
363
static int vmw_resources_validate(struct vmw_sw_context *sw_context)
324
{
364
{
325
	struct vmw_resource_val_node *val;
365
	struct vmw_resource_val_node *val;
326
	int ret;
366
	int ret;
327
 
367
 
328
	list_for_each_entry(val, &sw_context->resource_list, head) {
368
	list_for_each_entry(val, &sw_context->resource_list, head) {
329
		struct vmw_resource *res = val->res;
369
		struct vmw_resource *res = val->res;
330
 
370
 
331
		ret = vmw_resource_validate(res);
371
		ret = vmw_resource_validate(res);
332
		if (unlikely(ret != 0)) {
372
		if (unlikely(ret != 0)) {
333
			if (ret != -ERESTARTSYS)
373
			if (ret != -ERESTARTSYS)
334
				DRM_ERROR("Failed to validate resource.\n");
374
				DRM_ERROR("Failed to validate resource.\n");
335
			return ret;
375
			return ret;
336
		}
376
		}
337
	}
377
	}
338
	return 0;
378
	return 0;
339
}
379
}
340
 
380
 
341
/**
381
/**
342
 * vmw_cmd_res_check - Check that a resource is present and if so, put it
382
 * vmw_cmd_res_check - Check that a resource is present and if so, put it
343
 * on the resource validate list unless it's already there.
383
 * on the resource validate list unless it's already there.
344
 *
384
 *
345
 * @dev_priv: Pointer to a device private structure.
385
 * @dev_priv: Pointer to a device private structure.
346
 * @sw_context: Pointer to the software context.
386
 * @sw_context: Pointer to the software context.
347
 * @res_type: Resource type.
387
 * @res_type: Resource type.
348
 * @converter: User-space visisble type specific information.
388
 * @converter: User-space visisble type specific information.
349
 * @id: Pointer to the location in the command buffer currently being
389
 * @id: Pointer to the location in the command buffer currently being
350
 * parsed from where the user-space resource id handle is located.
390
 * parsed from where the user-space resource id handle is located.
351
 */
391
 */
352
static int vmw_cmd_res_check(struct vmw_private *dev_priv,
392
static int vmw_cmd_res_check(struct vmw_private *dev_priv,
353
			     struct vmw_sw_context *sw_context,
393
			     struct vmw_sw_context *sw_context,
354
			     enum vmw_res_type res_type,
394
			     enum vmw_res_type res_type,
355
			     const struct vmw_user_resource_conv *converter,
395
			     const struct vmw_user_resource_conv *converter,
356
			     uint32_t *id,
396
			     uint32_t *id,
357
			     struct vmw_resource_val_node **p_val)
397
			     struct vmw_resource_val_node **p_val)
358
{
398
{
359
	struct vmw_res_cache_entry *rcache =
399
	struct vmw_res_cache_entry *rcache =
360
		&sw_context->res_cache[res_type];
400
		&sw_context->res_cache[res_type];
361
	struct vmw_resource *res;
401
	struct vmw_resource *res;
362
	struct vmw_resource_val_node *node;
402
	struct vmw_resource_val_node *node;
363
	int ret;
403
	int ret;
364
 
404
 
-
 
405
	if (*id == SVGA3D_INVALID_ID) {
-
 
406
		if (p_val)
-
 
407
			*p_val = NULL;
-
 
408
		if (res_type == vmw_res_context) {
-
 
409
			DRM_ERROR("Illegal context invalid id.\n");
-
 
410
			return -EINVAL;
365
	if (*id == SVGA3D_INVALID_ID)
411
		}
-
 
412
		return 0;
366
		return 0;
413
	}
367
 
414
 
368
	/*
415
	/*
369
	 * Fastpath in case of repeated commands referencing the same
416
	 * Fastpath in case of repeated commands referencing the same
370
	 * resource
417
	 * resource
371
	 */
418
	 */
372
 
419
 
373
	if (likely(rcache->valid && *id == rcache->handle)) {
420
	if (likely(rcache->valid && *id == rcache->handle)) {
374
		const struct vmw_resource *res = rcache->res;
421
		const struct vmw_resource *res = rcache->res;
375
 
422
 
376
		rcache->node->first_usage = false;
423
		rcache->node->first_usage = false;
377
		if (p_val)
424
		if (p_val)
378
			*p_val = rcache->node;
425
			*p_val = rcache->node;
379
 
426
 
380
		return vmw_resource_relocation_add
427
		return vmw_resource_relocation_add
381
			(&sw_context->res_relocations, res,
428
			(&sw_context->res_relocations, res,
382
			 id - sw_context->buf_start);
429
			 id - sw_context->buf_start);
383
	}
430
	}
384
 
431
 
385
	ret = vmw_user_resource_lookup_handle(dev_priv,
432
	ret = vmw_user_resource_lookup_handle(dev_priv,
386
					      sw_context->tfile,
433
					      sw_context->tfile,
387
					      *id,
434
					      *id,
388
					      converter,
435
					      converter,
389
					      &res);
436
					      &res);
390
	if (unlikely(ret != 0)) {
437
	if (unlikely(ret != 0)) {
391
		DRM_ERROR("Could not find or use resource 0x%08x.\n",
438
		DRM_ERROR("Could not find or use resource 0x%08x.\n",
392
			  (unsigned) *id);
439
			  (unsigned) *id);
393
//       dump_stack();
440
//       dump_stack();
394
		return ret;
441
		return ret;
395
	}
442
	}
396
 
443
 
397
	rcache->valid = true;
444
	rcache->valid = true;
398
	rcache->res = res;
445
	rcache->res = res;
399
	rcache->handle = *id;
446
	rcache->handle = *id;
400
 
447
 
401
	ret = vmw_resource_relocation_add(&sw_context->res_relocations,
448
	ret = vmw_resource_relocation_add(&sw_context->res_relocations,
402
					  res,
449
					  res,
403
					  id - sw_context->buf_start);
450
					  id - sw_context->buf_start);
404
	if (unlikely(ret != 0))
451
	if (unlikely(ret != 0))
405
		goto out_no_reloc;
452
		goto out_no_reloc;
406
 
453
 
407
	ret = vmw_resource_val_add(sw_context, res, &node);
454
	ret = vmw_resource_val_add(sw_context, res, &node);
408
	if (unlikely(ret != 0))
455
	if (unlikely(ret != 0))
409
		goto out_no_reloc;
456
		goto out_no_reloc;
410
 
457
 
411
	rcache->node = node;
458
	rcache->node = node;
412
	if (p_val)
459
	if (p_val)
413
		*p_val = node;
460
		*p_val = node;
-
 
461
 
-
 
462
	if (node->first_usage && res_type == vmw_res_context) {
-
 
463
		node->staged_bindings =
-
 
464
			kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL);
-
 
465
		if (node->staged_bindings == NULL) {
-
 
466
			DRM_ERROR("Failed to allocate context binding "
-
 
467
				  "information.\n");
-
 
468
			goto out_no_reloc;
-
 
469
		}
-
 
470
		INIT_LIST_HEAD(&node->staged_bindings->list);
-
 
471
	}
-
 
472
 
414
	vmw_resource_unreference(&res);
473
	vmw_resource_unreference(&res);
415
	return 0;
474
	return 0;
416
 
475
 
417
out_no_reloc:
476
out_no_reloc:
418
	BUG_ON(sw_context->error_resource != NULL);
477
	BUG_ON(sw_context->error_resource != NULL);
419
	sw_context->error_resource = res;
478
	sw_context->error_resource = res;
420
 
479
 
421
	return ret;
480
	return ret;
422
}
481
}
423
 
482
 
424
/**
483
/**
425
 * vmw_cmd_cid_check - Check a command header for valid context information.
484
 * vmw_cmd_cid_check - Check a command header for valid context information.
426
 *
485
 *
427
 * @dev_priv: Pointer to a device private structure.
486
 * @dev_priv: Pointer to a device private structure.
428
 * @sw_context: Pointer to the software context.
487
 * @sw_context: Pointer to the software context.
429
 * @header: A command header with an embedded user-space context handle.
488
 * @header: A command header with an embedded user-space context handle.
430
 *
489
 *
431
 * Convenience function: Call vmw_cmd_res_check with the user-space context
490
 * Convenience function: Call vmw_cmd_res_check with the user-space context
432
 * handle embedded in @header.
491
 * handle embedded in @header.
433
 */
492
 */
434
static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
493
static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
435
			     struct vmw_sw_context *sw_context,
494
			     struct vmw_sw_context *sw_context,
436
			     SVGA3dCmdHeader *header)
495
			     SVGA3dCmdHeader *header)
437
{
496
{
438
	struct vmw_cid_cmd {
497
	struct vmw_cid_cmd {
439
		SVGA3dCmdHeader header;
498
		SVGA3dCmdHeader header;
440
		__le32 cid;
499
		__le32 cid;
441
	} *cmd;
500
	} *cmd;
442
 
501
 
443
	cmd = container_of(header, struct vmw_cid_cmd, header);
502
	cmd = container_of(header, struct vmw_cid_cmd, header);
444
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
503
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
445
				 user_context_converter, &cmd->cid, NULL);
504
				 user_context_converter, &cmd->cid, NULL);
446
}
505
}
447
 
506
 
448
static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
507
static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
449
					   struct vmw_sw_context *sw_context,
508
					   struct vmw_sw_context *sw_context,
450
					   SVGA3dCmdHeader *header)
509
					   SVGA3dCmdHeader *header)
451
{
510
{
452
	struct vmw_sid_cmd {
511
	struct vmw_sid_cmd {
453
		SVGA3dCmdHeader header;
512
		SVGA3dCmdHeader header;
454
		SVGA3dCmdSetRenderTarget body;
513
		SVGA3dCmdSetRenderTarget body;
455
	} *cmd;
514
	} *cmd;
-
 
515
	struct vmw_resource_val_node *ctx_node;
-
 
516
	struct vmw_resource_val_node *res_node;
456
	int ret;
517
	int ret;
-
 
518
 
-
 
519
	cmd = container_of(header, struct vmw_sid_cmd, header);
457
 
520
 
-
 
521
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
-
 
522
				user_context_converter, &cmd->body.cid,
458
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
523
				&ctx_node);
459
	if (unlikely(ret != 0))
524
	if (unlikely(ret != 0))
460
		return ret;
525
		return ret;
461
 
-
 
462
	cmd = container_of(header, struct vmw_sid_cmd, header);
526
 
463
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
527
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
464
				user_surface_converter,
528
				user_surface_converter,
-
 
529
				&cmd->body.target.sid, &res_node);
465
				&cmd->body.target.sid, NULL);
530
	if (unlikely(ret != 0))
-
 
531
	return ret;
-
 
532
 
-
 
533
	if (dev_priv->has_mob) {
-
 
534
		struct vmw_ctx_bindinfo bi;
-
 
535
 
-
 
536
		bi.ctx = ctx_node->res;
-
 
537
		bi.res = res_node ? res_node->res : NULL;
-
 
538
		bi.bt = vmw_ctx_binding_rt;
-
 
539
		bi.i1.rt_type = cmd->body.type;
-
 
540
		return vmw_context_binding_add(ctx_node->staged_bindings, &bi);
-
 
541
	}
-
 
542
 
466
	return ret;
543
	return 0;
467
}
544
}
468
 
545
 
469
static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
546
static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
470
				      struct vmw_sw_context *sw_context,
547
				      struct vmw_sw_context *sw_context,
471
				      SVGA3dCmdHeader *header)
548
				      SVGA3dCmdHeader *header)
472
{
549
{
473
	struct vmw_sid_cmd {
550
	struct vmw_sid_cmd {
474
		SVGA3dCmdHeader header;
551
		SVGA3dCmdHeader header;
475
		SVGA3dCmdSurfaceCopy body;
552
		SVGA3dCmdSurfaceCopy body;
476
	} *cmd;
553
	} *cmd;
477
	int ret;
554
	int ret;
478
 
555
 
479
	cmd = container_of(header, struct vmw_sid_cmd, header);
556
	cmd = container_of(header, struct vmw_sid_cmd, header);
480
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
557
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
481
				user_surface_converter,
558
				user_surface_converter,
482
				&cmd->body.src.sid, NULL);
559
				&cmd->body.src.sid, NULL);
483
	if (unlikely(ret != 0))
560
	if (unlikely(ret != 0))
484
		return ret;
561
		return ret;
485
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
562
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
486
				 user_surface_converter,
563
				 user_surface_converter,
487
				 &cmd->body.dest.sid, NULL);
564
				 &cmd->body.dest.sid, NULL);
488
}
565
}
489
 
566
 
490
static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
567
static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
491
				     struct vmw_sw_context *sw_context,
568
				     struct vmw_sw_context *sw_context,
492
				     SVGA3dCmdHeader *header)
569
				     SVGA3dCmdHeader *header)
493
{
570
{
494
	struct vmw_sid_cmd {
571
	struct vmw_sid_cmd {
495
		SVGA3dCmdHeader header;
572
		SVGA3dCmdHeader header;
496
		SVGA3dCmdSurfaceStretchBlt body;
573
		SVGA3dCmdSurfaceStretchBlt body;
497
	} *cmd;
574
	} *cmd;
498
	int ret;
575
	int ret;
499
 
576
 
500
	cmd = container_of(header, struct vmw_sid_cmd, header);
577
	cmd = container_of(header, struct vmw_sid_cmd, header);
501
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
578
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
502
				user_surface_converter,
579
				user_surface_converter,
503
				&cmd->body.src.sid, NULL);
580
				&cmd->body.src.sid, NULL);
504
	if (unlikely(ret != 0))
581
	if (unlikely(ret != 0))
505
		return ret;
582
		return ret;
506
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
583
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
507
				 user_surface_converter,
584
				 user_surface_converter,
508
				 &cmd->body.dest.sid, NULL);
585
				 &cmd->body.dest.sid, NULL);
509
}
586
}
510
 
587
 
511
static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
588
static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
512
					 struct vmw_sw_context *sw_context,
589
					 struct vmw_sw_context *sw_context,
513
					 SVGA3dCmdHeader *header)
590
					 SVGA3dCmdHeader *header)
514
{
591
{
515
	struct vmw_sid_cmd {
592
	struct vmw_sid_cmd {
516
		SVGA3dCmdHeader header;
593
		SVGA3dCmdHeader header;
517
		SVGA3dCmdBlitSurfaceToScreen body;
594
		SVGA3dCmdBlitSurfaceToScreen body;
518
	} *cmd;
595
	} *cmd;
519
 
596
 
520
	cmd = container_of(header, struct vmw_sid_cmd, header);
597
	cmd = container_of(header, struct vmw_sid_cmd, header);
521
 
-
 
522
	if (unlikely(!sw_context->kernel)) {
-
 
523
		DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
-
 
524
		return -EPERM;
-
 
525
	}
-
 
526
 
598
 
527
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
599
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
528
				 user_surface_converter,
600
				 user_surface_converter,
529
				 &cmd->body.srcImage.sid, NULL);
601
				 &cmd->body.srcImage.sid, NULL);
530
}
602
}
531
 
603
 
532
static int vmw_cmd_present_check(struct vmw_private *dev_priv,
604
static int vmw_cmd_present_check(struct vmw_private *dev_priv,
533
				 struct vmw_sw_context *sw_context,
605
				 struct vmw_sw_context *sw_context,
534
				 SVGA3dCmdHeader *header)
606
				 SVGA3dCmdHeader *header)
535
{
607
{
536
	struct vmw_sid_cmd {
608
	struct vmw_sid_cmd {
537
		SVGA3dCmdHeader header;
609
		SVGA3dCmdHeader header;
538
		SVGA3dCmdPresent body;
610
		SVGA3dCmdPresent body;
539
	} *cmd;
611
	} *cmd;
540
 
612
 
541
 
613
 
542
	cmd = container_of(header, struct vmw_sid_cmd, header);
614
	cmd = container_of(header, struct vmw_sid_cmd, header);
543
 
-
 
544
	if (unlikely(!sw_context->kernel)) {
-
 
545
		DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
-
 
546
		return -EPERM;
-
 
547
	}
-
 
548
 
615
 
549
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
616
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
550
				 user_surface_converter, &cmd->body.sid,
617
				 user_surface_converter, &cmd->body.sid,
551
				 NULL);
618
				 NULL);
552
}
619
}
553
 
620
 
554
/**
621
/**
555
 * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries.
622
 * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries.
556
 *
623
 *
557
 * @dev_priv: The device private structure.
624
 * @dev_priv: The device private structure.
558
 * @new_query_bo: The new buffer holding query results.
625
 * @new_query_bo: The new buffer holding query results.
559
 * @sw_context: The software context used for this command submission.
626
 * @sw_context: The software context used for this command submission.
560
 *
627
 *
561
 * This function checks whether @new_query_bo is suitable for holding
628
 * This function checks whether @new_query_bo is suitable for holding
562
 * query results, and if another buffer currently is pinned for query
629
 * query results, and if another buffer currently is pinned for query
563
 * results. If so, the function prepares the state of @sw_context for
630
 * results. If so, the function prepares the state of @sw_context for
564
 * switching pinned buffers after successful submission of the current
631
 * switching pinned buffers after successful submission of the current
565
 * command batch.
632
 * command batch.
566
 */
633
 */
567
static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
634
static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
568
				       struct ttm_buffer_object *new_query_bo,
635
				       struct ttm_buffer_object *new_query_bo,
569
				       struct vmw_sw_context *sw_context)
636
				       struct vmw_sw_context *sw_context)
570
{
637
{
571
	struct vmw_res_cache_entry *ctx_entry =
638
	struct vmw_res_cache_entry *ctx_entry =
572
		&sw_context->res_cache[vmw_res_context];
639
		&sw_context->res_cache[vmw_res_context];
573
	int ret;
640
	int ret;
574
 
641
 
575
	BUG_ON(!ctx_entry->valid);
642
	BUG_ON(!ctx_entry->valid);
576
	sw_context->last_query_ctx = ctx_entry->res;
643
	sw_context->last_query_ctx = ctx_entry->res;
577
 
644
 
578
	if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
645
	if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
579
 
646
 
580
		if (unlikely(new_query_bo->num_pages > 4)) {
647
		if (unlikely(new_query_bo->num_pages > 4)) {
581
			DRM_ERROR("Query buffer too large.\n");
648
			DRM_ERROR("Query buffer too large.\n");
582
			return -EINVAL;
649
			return -EINVAL;
583
		}
650
		}
584
 
651
 
585
		if (unlikely(sw_context->cur_query_bo != NULL)) {
652
		if (unlikely(sw_context->cur_query_bo != NULL)) {
586
			sw_context->needs_post_query_barrier = true;
653
			sw_context->needs_post_query_barrier = true;
587
			ret = vmw_bo_to_validate_list(sw_context,
654
			ret = vmw_bo_to_validate_list(sw_context,
588
						      sw_context->cur_query_bo,
655
						      sw_context->cur_query_bo,
589
						      NULL);
656
						      dev_priv->has_mob, NULL);
590
			if (unlikely(ret != 0))
657
			if (unlikely(ret != 0))
591
				return ret;
658
				return ret;
592
		}
659
		}
593
		sw_context->cur_query_bo = new_query_bo;
660
		sw_context->cur_query_bo = new_query_bo;
594
 
661
 
595
		ret = vmw_bo_to_validate_list(sw_context,
662
		ret = vmw_bo_to_validate_list(sw_context,
596
					      dev_priv->dummy_query_bo,
663
					      dev_priv->dummy_query_bo,
597
					      NULL);
664
					      dev_priv->has_mob, NULL);
598
		if (unlikely(ret != 0))
665
		if (unlikely(ret != 0))
599
			return ret;
666
			return ret;
600
 
667
 
601
	}
668
	}
602
 
669
 
603
	return 0;
670
	return 0;
604
}
671
}
605
 
672
 
606
 
673
 
607
/**
674
/**
608
 * vmw_query_bo_switch_commit - Finalize switching pinned query buffer
675
 * vmw_query_bo_switch_commit - Finalize switching pinned query buffer
609
 *
676
 *
610
 * @dev_priv: The device private structure.
677
 * @dev_priv: The device private structure.
611
 * @sw_context: The software context used for this command submission batch.
678
 * @sw_context: The software context used for this command submission batch.
612
 *
679
 *
613
 * This function will check if we're switching query buffers, and will then,
680
 * This function will check if we're switching query buffers, and will then,
614
 * issue a dummy occlusion query wait used as a query barrier. When the fence
681
 * issue a dummy occlusion query wait used as a query barrier. When the fence
615
 * object following that query wait has signaled, we are sure that all
682
 * object following that query wait has signaled, we are sure that all
616
 * preceding queries have finished, and the old query buffer can be unpinned.
683
 * preceding queries have finished, and the old query buffer can be unpinned.
617
 * However, since both the new query buffer and the old one are fenced with
684
 * However, since both the new query buffer and the old one are fenced with
618
 * that fence, we can do an asynchronus unpin now, and be sure that the
685
 * that fence, we can do an asynchronus unpin now, and be sure that the
619
 * old query buffer won't be moved until the fence has signaled.
686
 * old query buffer won't be moved until the fence has signaled.
620
 *
687
 *
621
 * As mentioned above, both the new - and old query buffers need to be fenced
688
 * As mentioned above, both the new - and old query buffers need to be fenced
622
 * using a sequence emitted *after* calling this function.
689
 * using a sequence emitted *after* calling this function.
623
 */
690
 */
624
static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
691
static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
625
				     struct vmw_sw_context *sw_context)
692
				     struct vmw_sw_context *sw_context)
626
{
693
{
627
	/*
694
	/*
628
	 * The validate list should still hold references to all
695
	 * The validate list should still hold references to all
629
	 * contexts here.
696
	 * contexts here.
630
	 */
697
	 */
631
 
698
 
632
	if (sw_context->needs_post_query_barrier) {
699
	if (sw_context->needs_post_query_barrier) {
633
		struct vmw_res_cache_entry *ctx_entry =
700
		struct vmw_res_cache_entry *ctx_entry =
634
			&sw_context->res_cache[vmw_res_context];
701
			&sw_context->res_cache[vmw_res_context];
635
		struct vmw_resource *ctx;
702
		struct vmw_resource *ctx;
636
		int ret;
703
		int ret;
637
 
704
 
638
		BUG_ON(!ctx_entry->valid);
705
		BUG_ON(!ctx_entry->valid);
639
		ctx = ctx_entry->res;
706
		ctx = ctx_entry->res;
640
 
707
 
641
		ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id);
708
		ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id);
642
 
709
 
643
		if (unlikely(ret != 0))
710
		if (unlikely(ret != 0))
644
			DRM_ERROR("Out of fifo space for dummy query.\n");
711
			DRM_ERROR("Out of fifo space for dummy query.\n");
645
	}
712
	}
646
 
713
 
647
	if (dev_priv->pinned_bo != sw_context->cur_query_bo) {
714
	if (dev_priv->pinned_bo != sw_context->cur_query_bo) {
648
		if (dev_priv->pinned_bo) {
715
		if (dev_priv->pinned_bo) {
649
			vmw_bo_pin(dev_priv->pinned_bo, false);
716
			vmw_bo_pin(dev_priv->pinned_bo, false);
650
			ttm_bo_unref(&dev_priv->pinned_bo);
717
			ttm_bo_unref(&dev_priv->pinned_bo);
651
		}
718
		}
652
 
719
 
653
		if (!sw_context->needs_post_query_barrier) {
720
		if (!sw_context->needs_post_query_barrier) {
654
			vmw_bo_pin(sw_context->cur_query_bo, true);
721
			vmw_bo_pin(sw_context->cur_query_bo, true);
655
 
722
 
656
			/*
723
			/*
657
			 * We pin also the dummy_query_bo buffer so that we
724
			 * We pin also the dummy_query_bo buffer so that we
658
			 * don't need to validate it when emitting
725
			 * don't need to validate it when emitting
659
			 * dummy queries in context destroy paths.
726
			 * dummy queries in context destroy paths.
660
			 */
727
			 */
661
 
728
 
662
			vmw_bo_pin(dev_priv->dummy_query_bo, true);
729
			vmw_bo_pin(dev_priv->dummy_query_bo, true);
663
			dev_priv->dummy_query_bo_pinned = true;
730
			dev_priv->dummy_query_bo_pinned = true;
664
 
731
 
665
			BUG_ON(sw_context->last_query_ctx == NULL);
732
			BUG_ON(sw_context->last_query_ctx == NULL);
666
			dev_priv->query_cid = sw_context->last_query_ctx->id;
733
			dev_priv->query_cid = sw_context->last_query_ctx->id;
667
			dev_priv->query_cid_valid = true;
734
			dev_priv->query_cid_valid = true;
668
			dev_priv->pinned_bo =
735
			dev_priv->pinned_bo =
669
				ttm_bo_reference(sw_context->cur_query_bo);
736
				ttm_bo_reference(sw_context->cur_query_bo);
670
		}
737
		}
671
	}
738
	}
672
}
739
}
673
 
740
 
674
/**
741
/**
-
 
742
 * vmw_translate_mob_pointer - Prepare to translate a user-space buffer
-
 
743
 * handle to a MOB id.
-
 
744
 *
-
 
745
 * @dev_priv: Pointer to a device private structure.
-
 
746
 * @sw_context: The software context used for this command batch validation.
-
 
747
 * @id: Pointer to the user-space handle to be translated.
-
 
748
 * @vmw_bo_p: Points to a location that, on successful return will carry
-
 
749
 * a reference-counted pointer to the DMA buffer identified by the
-
 
750
 * user-space handle in @id.
-
 
751
 *
-
 
752
 * This function saves information needed to translate a user-space buffer
-
 
753
 * handle to a MOB id. The translation does not take place immediately, but
-
 
754
 * during a call to vmw_apply_relocations(). This function builds a relocation
-
 
755
 * list and a list of buffers to validate. The former needs to be freed using
-
 
756
 * either vmw_apply_relocations() or vmw_free_relocations(). The latter
-
 
757
 * needs to be freed using vmw_clear_validations.
-
 
758
 */
-
 
759
static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
-
 
760
				 struct vmw_sw_context *sw_context,
-
 
761
				 SVGAMobId *id,
-
 
762
				 struct vmw_dma_buffer **vmw_bo_p)
-
 
763
{
-
 
764
	struct vmw_dma_buffer *vmw_bo = NULL;
-
 
765
	struct ttm_buffer_object *bo;
-
 
766
	uint32_t handle = *id;
-
 
767
	struct vmw_relocation *reloc;
-
 
768
	int ret;
-
 
769
 
-
 
770
	ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
-
 
771
	if (unlikely(ret != 0)) {
-
 
772
		DRM_ERROR("Could not find or use MOB buffer.\n");
-
 
773
		return -EINVAL;
-
 
774
	}
-
 
775
	bo = &vmw_bo->base;
-
 
776
 
-
 
777
	if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
-
 
778
		DRM_ERROR("Max number relocations per submission"
-
 
779
			  " exceeded\n");
-
 
780
		ret = -EINVAL;
-
 
781
		goto out_no_reloc;
-
 
782
	}
-
 
783
 
-
 
784
	reloc = &sw_context->relocs[sw_context->cur_reloc++];
-
 
785
	reloc->mob_loc = id;
-
 
786
	reloc->location = NULL;
-
 
787
 
-
 
788
	ret = vmw_bo_to_validate_list(sw_context, bo, true, &reloc->index);
-
 
789
	if (unlikely(ret != 0))
-
 
790
		goto out_no_reloc;
-
 
791
 
-
 
792
	*vmw_bo_p = vmw_bo;
-
 
793
	return 0;
-
 
794
 
-
 
795
out_no_reloc:
-
 
796
	vmw_dmabuf_unreference(&vmw_bo);
-
 
797
	vmw_bo_p = NULL;
-
 
798
	return ret;
-
 
799
}
-
 
800
 
-
 
801
/**
675
 * vmw_translate_guest_pointer - Prepare to translate a user-space buffer
802
 * vmw_translate_guest_pointer - Prepare to translate a user-space buffer
676
 * handle to a valid SVGAGuestPtr
803
 * handle to a valid SVGAGuestPtr
677
 *
804
 *
678
 * @dev_priv: Pointer to a device private structure.
805
 * @dev_priv: Pointer to a device private structure.
679
 * @sw_context: The software context used for this command batch validation.
806
 * @sw_context: The software context used for this command batch validation.
680
 * @ptr: Pointer to the user-space handle to be translated.
807
 * @ptr: Pointer to the user-space handle to be translated.
681
 * @vmw_bo_p: Points to a location that, on successful return will carry
808
 * @vmw_bo_p: Points to a location that, on successful return will carry
682
 * a reference-counted pointer to the DMA buffer identified by the
809
 * a reference-counted pointer to the DMA buffer identified by the
683
 * user-space handle in @id.
810
 * user-space handle in @id.
684
 *
811
 *
685
 * This function saves information needed to translate a user-space buffer
812
 * This function saves information needed to translate a user-space buffer
686
 * handle to a valid SVGAGuestPtr. The translation does not take place
813
 * handle to a valid SVGAGuestPtr. The translation does not take place
687
 * immediately, but during a call to vmw_apply_relocations().
814
 * immediately, but during a call to vmw_apply_relocations().
688
 * This function builds a relocation list and a list of buffers to validate.
815
 * This function builds a relocation list and a list of buffers to validate.
689
 * The former needs to be freed using either vmw_apply_relocations() or
816
 * The former needs to be freed using either vmw_apply_relocations() or
690
 * vmw_free_relocations(). The latter needs to be freed using
817
 * vmw_free_relocations(). The latter needs to be freed using
691
 * vmw_clear_validations.
818
 * vmw_clear_validations.
692
 */
819
 */
693
static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
820
static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
694
				   struct vmw_sw_context *sw_context,
821
				   struct vmw_sw_context *sw_context,
695
				   SVGAGuestPtr *ptr,
822
				   SVGAGuestPtr *ptr,
696
				   struct vmw_dma_buffer **vmw_bo_p)
823
				   struct vmw_dma_buffer **vmw_bo_p)
697
{
824
{
698
	struct vmw_dma_buffer *vmw_bo = NULL;
825
	struct vmw_dma_buffer *vmw_bo = NULL;
699
	struct ttm_buffer_object *bo;
826
	struct ttm_buffer_object *bo;
700
	uint32_t handle = ptr->gmrId;
827
	uint32_t handle = ptr->gmrId;
701
	struct vmw_relocation *reloc;
828
	struct vmw_relocation *reloc;
702
	int ret;
829
	int ret;
703
 
830
 
704
	ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
831
	ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
705
	if (unlikely(ret != 0)) {
832
	if (unlikely(ret != 0)) {
706
		DRM_ERROR("Could not find or use GMR region.\n");
833
		DRM_ERROR("Could not find or use GMR region.\n");
707
		return -EINVAL;
834
		return -EINVAL;
708
	}
835
	}
709
	bo = &vmw_bo->base;
836
	bo = &vmw_bo->base;
710
 
837
 
711
	if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
838
	if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
712
		DRM_ERROR("Max number relocations per submission"
839
		DRM_ERROR("Max number relocations per submission"
713
			  " exceeded\n");
840
			  " exceeded\n");
714
		ret = -EINVAL;
841
		ret = -EINVAL;
715
		goto out_no_reloc;
842
		goto out_no_reloc;
716
	}
843
	}
717
 
844
 
718
	reloc = &sw_context->relocs[sw_context->cur_reloc++];
845
	reloc = &sw_context->relocs[sw_context->cur_reloc++];
719
	reloc->location = ptr;
846
	reloc->location = ptr;
720
 
847
 
721
	ret = vmw_bo_to_validate_list(sw_context, bo, &reloc->index);
848
	ret = vmw_bo_to_validate_list(sw_context, bo, false, &reloc->index);
722
	if (unlikely(ret != 0))
849
	if (unlikely(ret != 0))
723
		goto out_no_reloc;
850
		goto out_no_reloc;
724
 
851
 
725
	*vmw_bo_p = vmw_bo;
852
	*vmw_bo_p = vmw_bo;
726
	return 0;
853
	return 0;
727
 
854
 
728
out_no_reloc:
855
out_no_reloc:
729
	vmw_dmabuf_unreference(&vmw_bo);
856
	vmw_dmabuf_unreference(&vmw_bo);
730
	vmw_bo_p = NULL;
857
	vmw_bo_p = NULL;
731
	return ret;
858
	return ret;
732
}
859
}
733
 
860
 
734
/**
861
/**
-
 
862
 * vmw_cmd_begin_gb_query - validate a  SVGA_3D_CMD_BEGIN_GB_QUERY command.
-
 
863
 *
-
 
864
 * @dev_priv: Pointer to a device private struct.
-
 
865
 * @sw_context: The software context used for this command submission.
-
 
866
 * @header: Pointer to the command header in the command stream.
-
 
867
 */
-
 
868
static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv,
-
 
869
				  struct vmw_sw_context *sw_context,
-
 
870
				  SVGA3dCmdHeader *header)
-
 
871
{
-
 
872
	struct vmw_begin_gb_query_cmd {
-
 
873
		SVGA3dCmdHeader header;
-
 
874
		SVGA3dCmdBeginGBQuery q;
-
 
875
	} *cmd;
-
 
876
 
-
 
877
	cmd = container_of(header, struct vmw_begin_gb_query_cmd,
-
 
878
			   header);
-
 
879
 
-
 
880
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
-
 
881
				 user_context_converter, &cmd->q.cid,
-
 
882
				 NULL);
-
 
883
}
-
 
884
 
-
 
885
/**
735
 * vmw_cmd_begin_query - validate a  SVGA_3D_CMD_BEGIN_QUERY command.
886
 * vmw_cmd_begin_query - validate a  SVGA_3D_CMD_BEGIN_QUERY command.
736
 *
887
 *
737
 * @dev_priv: Pointer to a device private struct.
888
 * @dev_priv: Pointer to a device private struct.
738
 * @sw_context: The software context used for this command submission.
889
 * @sw_context: The software context used for this command submission.
739
 * @header: Pointer to the command header in the command stream.
890
 * @header: Pointer to the command header in the command stream.
740
 */
891
 */
741
static int vmw_cmd_begin_query(struct vmw_private *dev_priv,
892
static int vmw_cmd_begin_query(struct vmw_private *dev_priv,
742
			       struct vmw_sw_context *sw_context,
893
			       struct vmw_sw_context *sw_context,
743
			       SVGA3dCmdHeader *header)
894
			       SVGA3dCmdHeader *header)
744
{
895
{
745
	struct vmw_begin_query_cmd {
896
	struct vmw_begin_query_cmd {
746
		SVGA3dCmdHeader header;
897
		SVGA3dCmdHeader header;
747
		SVGA3dCmdBeginQuery q;
898
		SVGA3dCmdBeginQuery q;
748
	} *cmd;
899
	} *cmd;
749
 
900
 
750
	cmd = container_of(header, struct vmw_begin_query_cmd,
901
	cmd = container_of(header, struct vmw_begin_query_cmd,
751
			   header);
902
			   header);
-
 
903
 
-
 
904
	if (unlikely(dev_priv->has_mob)) {
-
 
905
		struct {
-
 
906
			SVGA3dCmdHeader header;
-
 
907
			SVGA3dCmdBeginGBQuery q;
-
 
908
		} gb_cmd;
-
 
909
 
-
 
910
		BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
-
 
911
 
-
 
912
		gb_cmd.header.id = SVGA_3D_CMD_BEGIN_GB_QUERY;
-
 
913
		gb_cmd.header.size = cmd->header.size;
-
 
914
		gb_cmd.q.cid = cmd->q.cid;
-
 
915
		gb_cmd.q.type = cmd->q.type;
-
 
916
 
-
 
917
		memcpy(cmd, &gb_cmd, sizeof(*cmd));
-
 
918
		return vmw_cmd_begin_gb_query(dev_priv, sw_context, header);
-
 
919
	}
752
 
920
 
753
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
921
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
754
				 user_context_converter, &cmd->q.cid,
922
				 user_context_converter, &cmd->q.cid,
755
				 NULL);
923
				 NULL);
756
}
924
}
757
 
925
 
758
/**
926
/**
-
 
927
 * vmw_cmd_end_gb_query - validate a  SVGA_3D_CMD_END_GB_QUERY command.
-
 
928
 *
-
 
929
 * @dev_priv: Pointer to a device private struct.
-
 
930
 * @sw_context: The software context used for this command submission.
-
 
931
 * @header: Pointer to the command header in the command stream.
-
 
932
 */
-
 
933
static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv,
-
 
934
				struct vmw_sw_context *sw_context,
-
 
935
				SVGA3dCmdHeader *header)
-
 
936
{
-
 
937
	struct vmw_dma_buffer *vmw_bo;
-
 
938
	struct vmw_query_cmd {
-
 
939
		SVGA3dCmdHeader header;
-
 
940
		SVGA3dCmdEndGBQuery q;
-
 
941
	} *cmd;
-
 
942
	int ret;
-
 
943
 
-
 
944
	cmd = container_of(header, struct vmw_query_cmd, header);
-
 
945
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
-
 
946
	if (unlikely(ret != 0))
-
 
947
		return ret;
-
 
948
 
-
 
949
	ret = vmw_translate_mob_ptr(dev_priv, sw_context,
-
 
950
				    &cmd->q.mobid,
-
 
951
				    &vmw_bo);
-
 
952
	if (unlikely(ret != 0))
-
 
953
		return ret;
-
 
954
 
-
 
955
	ret = vmw_query_bo_switch_prepare(dev_priv, &vmw_bo->base, sw_context);
-
 
956
 
-
 
957
	vmw_dmabuf_unreference(&vmw_bo);
-
 
958
	return ret;
-
 
959
}
-
 
960
 
-
 
961
/**
759
 * vmw_cmd_end_query - validate a  SVGA_3D_CMD_END_QUERY command.
962
 * vmw_cmd_end_query - validate a  SVGA_3D_CMD_END_QUERY command.
760
 *
963
 *
761
 * @dev_priv: Pointer to a device private struct.
964
 * @dev_priv: Pointer to a device private struct.
762
 * @sw_context: The software context used for this command submission.
965
 * @sw_context: The software context used for this command submission.
763
 * @header: Pointer to the command header in the command stream.
966
 * @header: Pointer to the command header in the command stream.
764
 */
967
 */
765
static int vmw_cmd_end_query(struct vmw_private *dev_priv,
968
static int vmw_cmd_end_query(struct vmw_private *dev_priv,
766
			     struct vmw_sw_context *sw_context,
969
			     struct vmw_sw_context *sw_context,
767
			     SVGA3dCmdHeader *header)
970
			     SVGA3dCmdHeader *header)
768
{
971
{
769
	struct vmw_dma_buffer *vmw_bo;
972
	struct vmw_dma_buffer *vmw_bo;
770
	struct vmw_query_cmd {
973
	struct vmw_query_cmd {
771
		SVGA3dCmdHeader header;
974
		SVGA3dCmdHeader header;
772
		SVGA3dCmdEndQuery q;
975
		SVGA3dCmdEndQuery q;
773
	} *cmd;
976
	} *cmd;
774
	int ret;
977
	int ret;
775
 
978
 
776
	cmd = container_of(header, struct vmw_query_cmd, header);
979
	cmd = container_of(header, struct vmw_query_cmd, header);
-
 
980
	if (dev_priv->has_mob) {
-
 
981
		struct {
-
 
982
			SVGA3dCmdHeader header;
-
 
983
			SVGA3dCmdEndGBQuery q;
-
 
984
		} gb_cmd;
-
 
985
 
-
 
986
		BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
-
 
987
 
-
 
988
		gb_cmd.header.id = SVGA_3D_CMD_END_GB_QUERY;
-
 
989
		gb_cmd.header.size = cmd->header.size;
-
 
990
		gb_cmd.q.cid = cmd->q.cid;
-
 
991
		gb_cmd.q.type = cmd->q.type;
-
 
992
		gb_cmd.q.mobid = cmd->q.guestResult.gmrId;
-
 
993
		gb_cmd.q.offset = cmd->q.guestResult.offset;
-
 
994
 
-
 
995
		memcpy(cmd, &gb_cmd, sizeof(*cmd));
-
 
996
		return vmw_cmd_end_gb_query(dev_priv, sw_context, header);
-
 
997
	}
-
 
998
 
777
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
999
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
778
	if (unlikely(ret != 0))
1000
	if (unlikely(ret != 0))
779
		return ret;
1001
		return ret;
780
 
1002
 
781
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1003
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
782
				      &cmd->q.guestResult,
1004
				      &cmd->q.guestResult,
783
				      &vmw_bo);
1005
				      &vmw_bo);
784
	if (unlikely(ret != 0))
1006
	if (unlikely(ret != 0))
785
		return ret;
1007
		return ret;
786
 
1008
 
787
	ret = vmw_query_bo_switch_prepare(dev_priv, &vmw_bo->base, sw_context);
1009
	ret = vmw_query_bo_switch_prepare(dev_priv, &vmw_bo->base, sw_context);
788
 
1010
 
789
	vmw_dmabuf_unreference(&vmw_bo);
1011
	vmw_dmabuf_unreference(&vmw_bo);
790
	return ret;
1012
	return ret;
791
}
1013
}
792
 
1014
 
-
 
1015
/**
-
 
1016
 * vmw_cmd_wait_gb_query - validate a  SVGA_3D_CMD_WAIT_GB_QUERY command.
-
 
1017
 *
-
 
1018
 * @dev_priv: Pointer to a device private struct.
-
 
1019
 * @sw_context: The software context used for this command submission.
-
 
1020
 * @header: Pointer to the command header in the command stream.
-
 
1021
 */
-
 
1022
static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv,
-
 
1023
				 struct vmw_sw_context *sw_context,
-
 
1024
				 SVGA3dCmdHeader *header)
-
 
1025
{
-
 
1026
	struct vmw_dma_buffer *vmw_bo;
-
 
1027
	struct vmw_query_cmd {
-
 
1028
		SVGA3dCmdHeader header;
-
 
1029
		SVGA3dCmdWaitForGBQuery q;
-
 
1030
	} *cmd;
-
 
1031
	int ret;
-
 
1032
 
-
 
1033
	cmd = container_of(header, struct vmw_query_cmd, header);
-
 
1034
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
-
 
1035
	if (unlikely(ret != 0))
-
 
1036
		return ret;
-
 
1037
 
-
 
1038
	ret = vmw_translate_mob_ptr(dev_priv, sw_context,
-
 
1039
				    &cmd->q.mobid,
-
 
1040
				    &vmw_bo);
-
 
1041
	if (unlikely(ret != 0))
-
 
1042
		return ret;
-
 
1043
 
-
 
1044
	vmw_dmabuf_unreference(&vmw_bo);
-
 
1045
	return 0;
-
 
1046
}
-
 
1047
 
793
/*
1048
/**
794
 * vmw_cmd_wait_query - validate a  SVGA_3D_CMD_WAIT_QUERY command.
1049
 * vmw_cmd_wait_query - validate a  SVGA_3D_CMD_WAIT_QUERY command.
795
 *
1050
 *
796
 * @dev_priv: Pointer to a device private struct.
1051
 * @dev_priv: Pointer to a device private struct.
797
 * @sw_context: The software context used for this command submission.
1052
 * @sw_context: The software context used for this command submission.
798
 * @header: Pointer to the command header in the command stream.
1053
 * @header: Pointer to the command header in the command stream.
799
 */
1054
 */
800
static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
1055
static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
801
			      struct vmw_sw_context *sw_context,
1056
			      struct vmw_sw_context *sw_context,
802
			      SVGA3dCmdHeader *header)
1057
			      SVGA3dCmdHeader *header)
803
{
1058
{
804
	struct vmw_dma_buffer *vmw_bo;
1059
	struct vmw_dma_buffer *vmw_bo;
805
	struct vmw_query_cmd {
1060
	struct vmw_query_cmd {
806
		SVGA3dCmdHeader header;
1061
		SVGA3dCmdHeader header;
807
		SVGA3dCmdWaitForQuery q;
1062
		SVGA3dCmdWaitForQuery q;
808
	} *cmd;
1063
	} *cmd;
809
	int ret;
1064
	int ret;
810
 
1065
 
811
	cmd = container_of(header, struct vmw_query_cmd, header);
1066
	cmd = container_of(header, struct vmw_query_cmd, header);
-
 
1067
	if (dev_priv->has_mob) {
-
 
1068
		struct {
-
 
1069
			SVGA3dCmdHeader header;
-
 
1070
			SVGA3dCmdWaitForGBQuery q;
-
 
1071
		} gb_cmd;
-
 
1072
 
-
 
1073
		BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
-
 
1074
 
-
 
1075
		gb_cmd.header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY;
-
 
1076
		gb_cmd.header.size = cmd->header.size;
-
 
1077
		gb_cmd.q.cid = cmd->q.cid;
-
 
1078
		gb_cmd.q.type = cmd->q.type;
-
 
1079
		gb_cmd.q.mobid = cmd->q.guestResult.gmrId;
-
 
1080
		gb_cmd.q.offset = cmd->q.guestResult.offset;
-
 
1081
 
-
 
1082
		memcpy(cmd, &gb_cmd, sizeof(*cmd));
-
 
1083
		return vmw_cmd_wait_gb_query(dev_priv, sw_context, header);
-
 
1084
	}
-
 
1085
 
812
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1086
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
813
	if (unlikely(ret != 0))
1087
	if (unlikely(ret != 0))
814
		return ret;
1088
		return ret;
815
 
1089
 
816
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1090
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
817
				      &cmd->q.guestResult,
1091
				      &cmd->q.guestResult,
818
				      &vmw_bo);
1092
				      &vmw_bo);
819
	if (unlikely(ret != 0))
1093
	if (unlikely(ret != 0))
820
		return ret;
1094
		return ret;
821
 
1095
 
822
	vmw_dmabuf_unreference(&vmw_bo);
1096
	vmw_dmabuf_unreference(&vmw_bo);
823
	return 0;
1097
	return 0;
824
}
1098
}
825
 
1099
 
826
static int vmw_cmd_dma(struct vmw_private *dev_priv,
1100
static int vmw_cmd_dma(struct vmw_private *dev_priv,
827
		       struct vmw_sw_context *sw_context,
1101
		       struct vmw_sw_context *sw_context,
828
		       SVGA3dCmdHeader *header)
1102
		       SVGA3dCmdHeader *header)
829
{
1103
{
830
	struct vmw_dma_buffer *vmw_bo = NULL;
1104
	struct vmw_dma_buffer *vmw_bo = NULL;
831
	struct vmw_surface *srf = NULL;
1105
	struct vmw_surface *srf = NULL;
832
	struct vmw_dma_cmd {
1106
	struct vmw_dma_cmd {
833
		SVGA3dCmdHeader header;
1107
		SVGA3dCmdHeader header;
834
		SVGA3dCmdSurfaceDMA dma;
1108
		SVGA3dCmdSurfaceDMA dma;
835
	} *cmd;
1109
	} *cmd;
836
	int ret;
1110
	int ret;
837
 
1111
 
838
	cmd = container_of(header, struct vmw_dma_cmd, header);
1112
	cmd = container_of(header, struct vmw_dma_cmd, header);
839
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1113
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
840
				      &cmd->dma.guest.ptr,
1114
				      &cmd->dma.guest.ptr,
841
				      &vmw_bo);
1115
				      &vmw_bo);
842
	if (unlikely(ret != 0))
1116
	if (unlikely(ret != 0))
843
		return ret;
1117
		return ret;
844
 
1118
 
845
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1119
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
846
				user_surface_converter, &cmd->dma.host.sid,
1120
				user_surface_converter, &cmd->dma.host.sid,
847
				NULL);
1121
				NULL);
848
	if (unlikely(ret != 0)) {
1122
	if (unlikely(ret != 0)) {
849
		if (unlikely(ret != -ERESTARTSYS))
1123
		if (unlikely(ret != -ERESTARTSYS))
850
			DRM_ERROR("could not find surface for DMA.\n");
1124
			DRM_ERROR("could not find surface for DMA.\n");
851
		goto out_no_surface;
1125
		goto out_no_surface;
852
	}
1126
	}
853
 
1127
 
854
	srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res);
1128
	srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res);
855
 
1129
 
856
//   vmw_kms_cursor_snoop(srf, sw_context->tfile, &vmw_bo->base, header);
1130
//   vmw_kms_cursor_snoop(srf, sw_context->tfile, &vmw_bo->base, header);
857
 
1131
 
858
out_no_surface:
1132
out_no_surface:
859
	vmw_dmabuf_unreference(&vmw_bo);
1133
	vmw_dmabuf_unreference(&vmw_bo);
860
	return ret;
1134
	return ret;
861
}
1135
}
862
 
1136
 
863
static int vmw_cmd_draw(struct vmw_private *dev_priv,
1137
static int vmw_cmd_draw(struct vmw_private *dev_priv,
864
			struct vmw_sw_context *sw_context,
1138
			struct vmw_sw_context *sw_context,
865
			SVGA3dCmdHeader *header)
1139
			SVGA3dCmdHeader *header)
866
{
1140
{
867
	struct vmw_draw_cmd {
1141
	struct vmw_draw_cmd {
868
		SVGA3dCmdHeader header;
1142
		SVGA3dCmdHeader header;
869
		SVGA3dCmdDrawPrimitives body;
1143
		SVGA3dCmdDrawPrimitives body;
870
	} *cmd;
1144
	} *cmd;
871
	SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
1145
	SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
872
		(unsigned long)header + sizeof(*cmd));
1146
		(unsigned long)header + sizeof(*cmd));
873
	SVGA3dPrimitiveRange *range;
1147
	SVGA3dPrimitiveRange *range;
874
	uint32_t i;
1148
	uint32_t i;
875
	uint32_t maxnum;
1149
	uint32_t maxnum;
876
	int ret;
1150
	int ret;
877
 
1151
 
878
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1152
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
879
	if (unlikely(ret != 0))
1153
	if (unlikely(ret != 0))
880
		return ret;
1154
		return ret;
881
 
1155
 
882
	cmd = container_of(header, struct vmw_draw_cmd, header);
1156
	cmd = container_of(header, struct vmw_draw_cmd, header);
883
	maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
1157
	maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
884
 
1158
 
885
	if (unlikely(cmd->body.numVertexDecls > maxnum)) {
1159
	if (unlikely(cmd->body.numVertexDecls > maxnum)) {
886
		DRM_ERROR("Illegal number of vertex declarations.\n");
1160
		DRM_ERROR("Illegal number of vertex declarations.\n");
887
		return -EINVAL;
1161
		return -EINVAL;
888
	}
1162
	}
889
 
1163
 
890
	for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
1164
	for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
891
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1165
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
892
					user_surface_converter,
1166
					user_surface_converter,
893
					&decl->array.surfaceId, NULL);
1167
					&decl->array.surfaceId, NULL);
894
		if (unlikely(ret != 0))
1168
		if (unlikely(ret != 0))
895
			return ret;
1169
			return ret;
896
	}
1170
	}
897
 
1171
 
898
	maxnum = (header->size - sizeof(cmd->body) -
1172
	maxnum = (header->size - sizeof(cmd->body) -
899
		  cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
1173
		  cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
900
	if (unlikely(cmd->body.numRanges > maxnum)) {
1174
	if (unlikely(cmd->body.numRanges > maxnum)) {
901
		DRM_ERROR("Illegal number of index ranges.\n");
1175
		DRM_ERROR("Illegal number of index ranges.\n");
902
		return -EINVAL;
1176
		return -EINVAL;
903
	}
1177
	}
904
 
1178
 
905
	range = (SVGA3dPrimitiveRange *) decl;
1179
	range = (SVGA3dPrimitiveRange *) decl;
906
	for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
1180
	for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
907
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1181
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
908
					user_surface_converter,
1182
					user_surface_converter,
909
					&range->indexArray.surfaceId, NULL);
1183
					&range->indexArray.surfaceId, NULL);
910
		if (unlikely(ret != 0))
1184
		if (unlikely(ret != 0))
911
			return ret;
1185
			return ret;
912
	}
1186
	}
913
	return 0;
1187
	return 0;
914
}
1188
}
915
 
1189
 
916
 
1190
 
917
static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
1191
static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
918
			     struct vmw_sw_context *sw_context,
1192
			     struct vmw_sw_context *sw_context,
919
			     SVGA3dCmdHeader *header)
1193
			     SVGA3dCmdHeader *header)
920
{
1194
{
921
	struct vmw_tex_state_cmd {
1195
	struct vmw_tex_state_cmd {
922
		SVGA3dCmdHeader header;
1196
		SVGA3dCmdHeader header;
923
		SVGA3dCmdSetTextureState state;
1197
		SVGA3dCmdSetTextureState state;
924
	};
1198
	} *cmd;
925
 
1199
 
926
	SVGA3dTextureState *last_state = (SVGA3dTextureState *)
1200
	SVGA3dTextureState *last_state = (SVGA3dTextureState *)
927
	  ((unsigned long) header + header->size + sizeof(header));
1201
	  ((unsigned long) header + header->size + sizeof(header));
928
	SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
1202
	SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
929
		((unsigned long) header + sizeof(struct vmw_tex_state_cmd));
1203
		((unsigned long) header + sizeof(struct vmw_tex_state_cmd));
-
 
1204
	struct vmw_resource_val_node *ctx_node;
-
 
1205
	struct vmw_resource_val_node *res_node;
930
	int ret;
1206
	int ret;
-
 
1207
 
-
 
1208
	cmd = container_of(header, struct vmw_tex_state_cmd,
-
 
1209
			   header);
931
 
1210
 
-
 
1211
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
-
 
1212
				user_context_converter, &cmd->state.cid,
932
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1213
				&ctx_node);
933
	if (unlikely(ret != 0))
1214
	if (unlikely(ret != 0))
934
		return ret;
1215
		return ret;
935
 
1216
 
936
	for (; cur_state < last_state; ++cur_state) {
1217
	for (; cur_state < last_state; ++cur_state) {
937
		if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
1218
		if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
938
			continue;
1219
			continue;
939
 
1220
 
940
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1221
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
941
					user_surface_converter,
1222
					user_surface_converter,
942
					&cur_state->value, NULL);
1223
					&cur_state->value, &res_node);
943
		if (unlikely(ret != 0))
1224
		if (unlikely(ret != 0))
944
			return ret;
1225
			return ret;
-
 
1226
 
-
 
1227
		if (dev_priv->has_mob) {
-
 
1228
			struct vmw_ctx_bindinfo bi;
-
 
1229
 
-
 
1230
			bi.ctx = ctx_node->res;
-
 
1231
			bi.res = res_node ? res_node->res : NULL;
-
 
1232
			bi.bt = vmw_ctx_binding_tex;
-
 
1233
			bi.i1.texture_stage = cur_state->stage;
-
 
1234
			vmw_context_binding_add(ctx_node->staged_bindings,
-
 
1235
						&bi);
-
 
1236
		}
945
	}
1237
	}
946
 
1238
 
947
	return 0;
1239
	return 0;
948
}
1240
}
949
 
1241
 
950
static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
1242
static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
951
				      struct vmw_sw_context *sw_context,
1243
				      struct vmw_sw_context *sw_context,
952
				      void *buf)
1244
				      void *buf)
953
{
1245
{
954
	struct vmw_dma_buffer *vmw_bo;
1246
	struct vmw_dma_buffer *vmw_bo;
955
	int ret;
1247
	int ret;
956
 
1248
 
957
	struct {
1249
	struct {
958
		uint32_t header;
1250
		uint32_t header;
959
		SVGAFifoCmdDefineGMRFB body;
1251
		SVGAFifoCmdDefineGMRFB body;
960
	} *cmd = buf;
1252
	} *cmd = buf;
961
 
1253
 
962
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1254
	ret = vmw_translate_guest_ptr(dev_priv, sw_context,
963
				      &cmd->body.ptr,
1255
				      &cmd->body.ptr,
964
				      &vmw_bo);
1256
				      &vmw_bo);
965
	if (unlikely(ret != 0))
1257
	if (unlikely(ret != 0))
966
		return ret;
1258
		return ret;
967
 
1259
 
968
	vmw_dmabuf_unreference(&vmw_bo);
1260
	vmw_dmabuf_unreference(&vmw_bo);
969
 
1261
 
970
	return ret;
1262
	return ret;
971
}
1263
}
972
 
1264
 
973
/**
1265
/**
-
 
1266
 * vmw_cmd_switch_backup - Utility function to handle backup buffer switching
-
 
1267
 *
-
 
1268
 * @dev_priv: Pointer to a device private struct.
-
 
1269
 * @sw_context: The software context being used for this batch.
-
 
1270
 * @res_type: The resource type.
-
 
1271
 * @converter: Information about user-space binding for this resource type.
-
 
1272
 * @res_id: Pointer to the user-space resource handle in the command stream.
-
 
1273
 * @buf_id: Pointer to the user-space backup buffer handle in the command
-
 
1274
 * stream.
-
 
1275
 * @backup_offset: Offset of backup into MOB.
-
 
1276
 *
-
 
1277
 * This function prepares for registering a switch of backup buffers
-
 
1278
 * in the resource metadata just prior to unreserving.
-
 
1279
 */
-
 
1280
static int vmw_cmd_switch_backup(struct vmw_private *dev_priv,
-
 
1281
				 struct vmw_sw_context *sw_context,
-
 
1282
				 enum vmw_res_type res_type,
-
 
1283
				 const struct vmw_user_resource_conv
-
 
1284
				 *converter,
-
 
1285
				 uint32_t *res_id,
-
 
1286
				 uint32_t *buf_id,
-
 
1287
				 unsigned long backup_offset)
-
 
1288
{
-
 
1289
	int ret;
-
 
1290
	struct vmw_dma_buffer *dma_buf;
-
 
1291
	struct vmw_resource_val_node *val_node;
-
 
1292
 
-
 
1293
	ret = vmw_cmd_res_check(dev_priv, sw_context, res_type,
-
 
1294
				converter, res_id, &val_node);
-
 
1295
	if (unlikely(ret != 0))
-
 
1296
		return ret;
-
 
1297
 
-
 
1298
	ret = vmw_translate_mob_ptr(dev_priv, sw_context, buf_id, &dma_buf);
-
 
1299
	if (unlikely(ret != 0))
-
 
1300
		return ret;
-
 
1301
 
-
 
1302
	if (val_node->first_usage)
-
 
1303
		val_node->no_buffer_needed = true;
-
 
1304
 
-
 
1305
	vmw_dmabuf_unreference(&val_node->new_backup);
-
 
1306
	val_node->new_backup = dma_buf;
-
 
1307
	val_node->new_backup_offset = backup_offset;
-
 
1308
 
-
 
1309
	return 0;
-
 
1310
}
-
 
1311
 
-
 
1312
/**
-
 
1313
 * vmw_cmd_bind_gb_surface - Validate an SVGA_3D_CMD_BIND_GB_SURFACE
-
 
1314
 * command
-
 
1315
 *
-
 
1316
 * @dev_priv: Pointer to a device private struct.
-
 
1317
 * @sw_context: The software context being used for this batch.
-
 
1318
 * @header: Pointer to the command header in the command stream.
-
 
1319
 */
-
 
1320
static int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv,
-
 
1321
				   struct vmw_sw_context *sw_context,
-
 
1322
				   SVGA3dCmdHeader *header)
-
 
1323
{
-
 
1324
	struct vmw_bind_gb_surface_cmd {
-
 
1325
		SVGA3dCmdHeader header;
-
 
1326
		SVGA3dCmdBindGBSurface body;
-
 
1327
	} *cmd;
-
 
1328
 
-
 
1329
	cmd = container_of(header, struct vmw_bind_gb_surface_cmd, header);
-
 
1330
 
-
 
1331
	return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface,
-
 
1332
				     user_surface_converter,
-
 
1333
				     &cmd->body.sid, &cmd->body.mobid,
-
 
1334
				     0);
-
 
1335
}
-
 
1336
 
-
 
1337
/**
-
 
1338
 * vmw_cmd_update_gb_image - Validate an SVGA_3D_CMD_UPDATE_GB_IMAGE
-
 
1339
 * command
-
 
1340
 *
-
 
1341
 * @dev_priv: Pointer to a device private struct.
-
 
1342
 * @sw_context: The software context being used for this batch.
-
 
1343
 * @header: Pointer to the command header in the command stream.
-
 
1344
 */
-
 
1345
static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv,
-
 
1346
				   struct vmw_sw_context *sw_context,
-
 
1347
				   SVGA3dCmdHeader *header)
-
 
1348
{
-
 
1349
	struct vmw_gb_surface_cmd {
-
 
1350
		SVGA3dCmdHeader header;
-
 
1351
		SVGA3dCmdUpdateGBImage body;
-
 
1352
	} *cmd;
-
 
1353
 
-
 
1354
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1355
 
-
 
1356
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1357
				 user_surface_converter,
-
 
1358
				 &cmd->body.image.sid, NULL);
-
 
1359
}
-
 
1360
 
-
 
1361
/**
-
 
1362
 * vmw_cmd_update_gb_surface - Validate an SVGA_3D_CMD_UPDATE_GB_SURFACE
-
 
1363
 * command
-
 
1364
 *
-
 
1365
 * @dev_priv: Pointer to a device private struct.
-
 
1366
 * @sw_context: The software context being used for this batch.
-
 
1367
 * @header: Pointer to the command header in the command stream.
-
 
1368
 */
-
 
1369
static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv,
-
 
1370
				     struct vmw_sw_context *sw_context,
-
 
1371
				     SVGA3dCmdHeader *header)
-
 
1372
{
-
 
1373
	struct vmw_gb_surface_cmd {
-
 
1374
		SVGA3dCmdHeader header;
-
 
1375
		SVGA3dCmdUpdateGBSurface body;
-
 
1376
	} *cmd;
-
 
1377
 
-
 
1378
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1379
 
-
 
1380
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1381
				 user_surface_converter,
-
 
1382
				 &cmd->body.sid, NULL);
-
 
1383
}
-
 
1384
 
-
 
1385
/**
-
 
1386
 * vmw_cmd_readback_gb_image - Validate an SVGA_3D_CMD_READBACK_GB_IMAGE
-
 
1387
 * command
-
 
1388
 *
-
 
1389
 * @dev_priv: Pointer to a device private struct.
-
 
1390
 * @sw_context: The software context being used for this batch.
-
 
1391
 * @header: Pointer to the command header in the command stream.
-
 
1392
 */
-
 
1393
static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv,
-
 
1394
				     struct vmw_sw_context *sw_context,
-
 
1395
				     SVGA3dCmdHeader *header)
-
 
1396
{
-
 
1397
	struct vmw_gb_surface_cmd {
-
 
1398
		SVGA3dCmdHeader header;
-
 
1399
		SVGA3dCmdReadbackGBImage body;
-
 
1400
	} *cmd;
-
 
1401
 
-
 
1402
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1403
 
-
 
1404
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1405
				 user_surface_converter,
-
 
1406
				 &cmd->body.image.sid, NULL);
-
 
1407
}
-
 
1408
 
-
 
1409
/**
-
 
1410
 * vmw_cmd_readback_gb_surface - Validate an SVGA_3D_CMD_READBACK_GB_SURFACE
-
 
1411
 * command
-
 
1412
 *
-
 
1413
 * @dev_priv: Pointer to a device private struct.
-
 
1414
 * @sw_context: The software context being used for this batch.
-
 
1415
 * @header: Pointer to the command header in the command stream.
-
 
1416
 */
-
 
1417
static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv,
-
 
1418
				       struct vmw_sw_context *sw_context,
-
 
1419
				       SVGA3dCmdHeader *header)
-
 
1420
{
-
 
1421
	struct vmw_gb_surface_cmd {
-
 
1422
		SVGA3dCmdHeader header;
-
 
1423
		SVGA3dCmdReadbackGBSurface body;
-
 
1424
	} *cmd;
-
 
1425
 
-
 
1426
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1427
 
-
 
1428
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1429
				 user_surface_converter,
-
 
1430
				 &cmd->body.sid, NULL);
-
 
1431
}
-
 
1432
 
-
 
1433
/**
-
 
1434
 * vmw_cmd_invalidate_gb_image - Validate an SVGA_3D_CMD_INVALIDATE_GB_IMAGE
-
 
1435
 * command
-
 
1436
 *
-
 
1437
 * @dev_priv: Pointer to a device private struct.
-
 
1438
 * @sw_context: The software context being used for this batch.
-
 
1439
 * @header: Pointer to the command header in the command stream.
-
 
1440
 */
-
 
1441
static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv,
-
 
1442
				       struct vmw_sw_context *sw_context,
-
 
1443
				       SVGA3dCmdHeader *header)
-
 
1444
{
-
 
1445
	struct vmw_gb_surface_cmd {
-
 
1446
		SVGA3dCmdHeader header;
-
 
1447
		SVGA3dCmdInvalidateGBImage body;
-
 
1448
	} *cmd;
-
 
1449
 
-
 
1450
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1451
 
-
 
1452
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1453
				 user_surface_converter,
-
 
1454
				 &cmd->body.image.sid, NULL);
-
 
1455
}
-
 
1456
 
-
 
1457
/**
-
 
1458
 * vmw_cmd_invalidate_gb_surface - Validate an
-
 
1459
 * SVGA_3D_CMD_INVALIDATE_GB_SURFACE command
-
 
1460
 *
-
 
1461
 * @dev_priv: Pointer to a device private struct.
-
 
1462
 * @sw_context: The software context being used for this batch.
-
 
1463
 * @header: Pointer to the command header in the command stream.
-
 
1464
 */
-
 
1465
static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv,
-
 
1466
					 struct vmw_sw_context *sw_context,
-
 
1467
					 SVGA3dCmdHeader *header)
-
 
1468
{
-
 
1469
	struct vmw_gb_surface_cmd {
-
 
1470
		SVGA3dCmdHeader header;
-
 
1471
		SVGA3dCmdInvalidateGBSurface body;
-
 
1472
	} *cmd;
-
 
1473
 
-
 
1474
	cmd = container_of(header, struct vmw_gb_surface_cmd, header);
-
 
1475
 
-
 
1476
	return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
-
 
1477
				 user_surface_converter,
-
 
1478
				 &cmd->body.sid, NULL);
-
 
1479
}
-
 
1480
 
-
 
1481
/**
974
 * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER
1482
 * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER
975
 * command
1483
 * command
976
 *
1484
 *
977
 * @dev_priv: Pointer to a device private struct.
1485
 * @dev_priv: Pointer to a device private struct.
978
 * @sw_context: The software context being used for this batch.
1486
 * @sw_context: The software context being used for this batch.
979
 * @header: Pointer to the command header in the command stream.
1487
 * @header: Pointer to the command header in the command stream.
980
 */
1488
 */
981
static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
1489
static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
982
			      struct vmw_sw_context *sw_context,
1490
			      struct vmw_sw_context *sw_context,
983
			      SVGA3dCmdHeader *header)
1491
			      SVGA3dCmdHeader *header)
984
{
1492
{
985
	struct vmw_set_shader_cmd {
1493
	struct vmw_set_shader_cmd {
986
		SVGA3dCmdHeader header;
1494
		SVGA3dCmdHeader header;
987
		SVGA3dCmdSetShader body;
1495
		SVGA3dCmdSetShader body;
988
	} *cmd;
1496
	} *cmd;
-
 
1497
	struct vmw_resource_val_node *ctx_node;
989
	int ret;
1498
	int ret;
990
 
1499
 
991
	cmd = container_of(header, struct vmw_set_shader_cmd,
1500
	cmd = container_of(header, struct vmw_set_shader_cmd,
992
			   header);
1501
			   header);
993
 
1502
 
-
 
1503
	ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
-
 
1504
				user_context_converter, &cmd->body.cid,
994
	ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1505
				&ctx_node);
995
	if (unlikely(ret != 0))
1506
	if (unlikely(ret != 0))
996
		return ret;
1507
		return ret;
-
 
1508
 
-
 
1509
	if (dev_priv->has_mob) {
-
 
1510
		struct vmw_ctx_bindinfo bi;
-
 
1511
		struct vmw_resource_val_node *res_node;
-
 
1512
 
-
 
1513
		ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_shader,
-
 
1514
					user_shader_converter,
-
 
1515
					&cmd->body.shid, &res_node);
-
 
1516
	if (unlikely(ret != 0))
-
 
1517
		return ret;
-
 
1518
 
-
 
1519
		bi.ctx = ctx_node->res;
-
 
1520
		bi.res = res_node ? res_node->res : NULL;
-
 
1521
		bi.bt = vmw_ctx_binding_shader;
-
 
1522
		bi.i1.shader_type = cmd->body.type;
-
 
1523
		return vmw_context_binding_add(ctx_node->staged_bindings, &bi);
-
 
1524
	}
997
 
1525
 
998
	return 0;
1526
	return 0;
999
}
1527
}
-
 
1528
 
-
 
1529
/**
-
 
1530
 * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER
-
 
1531
 * command
-
 
1532
 *
-
 
1533
 * @dev_priv: Pointer to a device private struct.
-
 
1534
 * @sw_context: The software context being used for this batch.
-
 
1535
 * @header: Pointer to the command header in the command stream.
-
 
1536
 */
-
 
1537
static int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv,
-
 
1538
				  struct vmw_sw_context *sw_context,
-
 
1539
				  SVGA3dCmdHeader *header)
-
 
1540
{
-
 
1541
	struct vmw_bind_gb_shader_cmd {
-
 
1542
		SVGA3dCmdHeader header;
-
 
1543
		SVGA3dCmdBindGBShader body;
-
 
1544
	} *cmd;
-
 
1545
 
-
 
1546
	cmd = container_of(header, struct vmw_bind_gb_shader_cmd,
-
 
1547
			   header);
-
 
1548
 
-
 
1549
	return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader,
-
 
1550
				     user_shader_converter,
-
 
1551
				     &cmd->body.shid, &cmd->body.mobid,
-
 
1552
				     cmd->body.offsetInBytes);
-
 
1553
}
1000
 
1554
 
1001
static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
1555
static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
1002
				struct vmw_sw_context *sw_context,
1556
				struct vmw_sw_context *sw_context,
1003
				void *buf, uint32_t *size)
1557
				void *buf, uint32_t *size)
1004
{
1558
{
1005
	uint32_t size_remaining = *size;
1559
	uint32_t size_remaining = *size;
1006
	uint32_t cmd_id;
1560
	uint32_t cmd_id;
1007
 
1561
 
1008
	cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
1562
	cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
1009
	switch (cmd_id) {
1563
	switch (cmd_id) {
1010
	case SVGA_CMD_UPDATE:
1564
	case SVGA_CMD_UPDATE:
1011
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate);
1565
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate);
1012
		break;
1566
		break;
1013
	case SVGA_CMD_DEFINE_GMRFB:
1567
	case SVGA_CMD_DEFINE_GMRFB:
1014
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB);
1568
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB);
1015
		break;
1569
		break;
1016
	case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
1570
	case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
1017
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
1571
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
1018
		break;
1572
		break;
1019
	case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
1573
	case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
1020
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
1574
		*size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
1021
		break;
1575
		break;
1022
	default:
1576
	default:
1023
		DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id);
1577
		DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id);
1024
		return -EINVAL;
1578
		return -EINVAL;
1025
	}
1579
	}
1026
 
1580
 
1027
	if (*size > size_remaining) {
1581
	if (*size > size_remaining) {
1028
		DRM_ERROR("Invalid SVGA command (size mismatch):"
1582
		DRM_ERROR("Invalid SVGA command (size mismatch):"
1029
			  " %u.\n", cmd_id);
1583
			  " %u.\n", cmd_id);
1030
		return -EINVAL;
1584
		return -EINVAL;
1031
	}
1585
	}
1032
 
1586
 
1033
	if (unlikely(!sw_context->kernel)) {
1587
	if (unlikely(!sw_context->kernel)) {
1034
		DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id);
1588
		DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id);
1035
		return -EPERM;
1589
		return -EPERM;
1036
	}
1590
	}
1037
 
1591
 
1038
	if (cmd_id == SVGA_CMD_DEFINE_GMRFB)
1592
	if (cmd_id == SVGA_CMD_DEFINE_GMRFB)
1039
		return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf);
1593
		return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf);
1040
 
1594
 
1041
	return 0;
1595
	return 0;
1042
}
1596
}
1043
 
-
 
1044
typedef int (*vmw_cmd_func) (struct vmw_private *,
-
 
1045
			     struct vmw_sw_context *,
-
 
1046
			     SVGA3dCmdHeader *);
-
 
1047
 
-
 
1048
#define VMW_CMD_DEF(cmd, func) \
-
 
1049
	[cmd - SVGA_3D_CMD_BASE] = func
-
 
1050
 
1597
 
1051
static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = {
1598
static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
-
 
1599
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid,
1052
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid),
1600
		    false, false, false),
-
 
1601
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid,
1053
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid),
1602
		    false, false, false),
-
 
1603
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check,
1054
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check),
1604
		    true, false, false),
-
 
1605
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check,
1055
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check),
1606
		    true, false, false),
-
 
1607
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma,
1056
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma),
1608
		    true, false, false),
-
 
1609
	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid,
1057
	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid),
1610
		    false, false, false),
-
 
1611
	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid,
1058
	VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid),
1612
		    false, false, false),
-
 
1613
	VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check,
1059
	VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check),
1614
		    true, false, false),
-
 
1615
	VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check,
1060
	VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check),
1616
		    true, false, false),
-
 
1617
	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check,
1061
	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check),
1618
		    true, false, false),
1062
	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
1619
	VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
1063
		    &vmw_cmd_set_render_target_check),
1620
		    &vmw_cmd_set_render_target_check, true, false, false),
-
 
1621
	VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state,
1064
	VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state),
1622
		    true, false, false),
-
 
1623
	VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check,
1065
	VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check),
1624
		    true, false, false),
-
 
1625
	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check,
1066
	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check),
1626
		    true, false, false),
-
 
1627
	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check,
1067
	VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check),
1628
		    true, false, false),
-
 
1629
	VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check,
1068
	VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check),
1630
		    true, false, false),
-
 
1631
	VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check,
1069
	VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check),
1632
		    true, false, false),
-
 
1633
	VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check,
1070
	VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check),
1634
		    true, false, false),
-
 
1635
	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check,
1071
	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check),
1636
		    false, false, false),
-
 
1637
	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check,
1072
	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check),
1638
		    true, true, false),
-
 
1639
	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check,
1073
	VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check),
1640
		    true, true, false),
-
 
1641
	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader,
1074
	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader),
1642
		    true, false, false),
-
 
1643
	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check,
1075
	VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check),
1644
		    true, true, false),
-
 
1645
	VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw,
1076
	VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw),
1646
		    true, false, false),
-
 
1647
	VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check,
1077
	VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check),
1648
		    true, false, false),
-
 
1649
	VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_begin_query,
1078
	VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_begin_query),
1650
		    true, false, false),
-
 
1651
	VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query,
1079
	VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query),
1652
		    true, false, false),
-
 
1653
	VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query,
1080
	VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query),
1654
		    true, false, false),
-
 
1655
	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok,
1081
	VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok),
1656
		    true, false, false),
1082
	VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
1657
	VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
1083
		    &vmw_cmd_blt_surf_screen_check),
1658
		    &vmw_cmd_blt_surf_screen_check, false, false, false),
-
 
1659
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE_V2, &vmw_cmd_invalid,
1084
	VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE_V2, &vmw_cmd_invalid),
1660
		    false, false, false),
-
 
1661
	VMW_CMD_DEF(SVGA_3D_CMD_GENERATE_MIPMAPS, &vmw_cmd_invalid,
1085
	VMW_CMD_DEF(SVGA_3D_CMD_GENERATE_MIPMAPS, &vmw_cmd_invalid),
1662
		    false, false, false),
-
 
1663
	VMW_CMD_DEF(SVGA_3D_CMD_ACTIVATE_SURFACE, &vmw_cmd_invalid,
1086
	VMW_CMD_DEF(SVGA_3D_CMD_ACTIVATE_SURFACE, &vmw_cmd_invalid),
1664
		    false, false, false),
-
 
1665
	VMW_CMD_DEF(SVGA_3D_CMD_DEACTIVATE_SURFACE, &vmw_cmd_invalid,
-
 
1666
		    false, false, false),
-
 
1667
	VMW_CMD_DEF(SVGA_3D_CMD_SCREEN_DMA, &vmw_cmd_invalid,
-
 
1668
		    false, false, false),
-
 
1669
	VMW_CMD_DEF(SVGA_3D_CMD_SET_UNITY_SURFACE_COOKIE, &vmw_cmd_invalid,
-
 
1670
		    false, false, false),
-
 
1671
	VMW_CMD_DEF(SVGA_3D_CMD_OPEN_CONTEXT_SURFACE, &vmw_cmd_invalid,
-
 
1672
		    false, false, false),
-
 
1673
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_BITBLT, &vmw_cmd_invalid,
-
 
1674
		    false, false, false),
-
 
1675
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_TRANSBLT, &vmw_cmd_invalid,
-
 
1676
		    false, false, false),
-
 
1677
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_STRETCHBLT, &vmw_cmd_invalid,
-
 
1678
		    false, false, false),
-
 
1679
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_COLORFILL, &vmw_cmd_invalid,
-
 
1680
		    false, false, false),
-
 
1681
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_ALPHABLEND, &vmw_cmd_invalid,
-
 
1682
		    false, false, false),
-
 
1683
	VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND, &vmw_cmd_invalid,
-
 
1684
		    false, false, false),
-
 
1685
	VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE, &vmw_cmd_invalid,
-
 
1686
		    false, false, true),
-
 
1687
	VMW_CMD_DEF(SVGA_3D_CMD_READBACK_OTABLE, &vmw_cmd_invalid,
-
 
1688
		    false, false, true),
-
 
1689
	VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_MOB, &vmw_cmd_invalid,
-
 
1690
		    false, false, true),
-
 
1691
	VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_MOB, &vmw_cmd_invalid,
-
 
1692
		    false, false, true),
-
 
1693
	VMW_CMD_DEF(SVGA_3D_CMD_REDEFINE_GB_MOB, &vmw_cmd_invalid,
-
 
1694
		    false, false, true),
-
 
1695
	VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING, &vmw_cmd_invalid,
-
 
1696
		    false, false, true),
-
 
1697
	VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE, &vmw_cmd_invalid,
-
 
1698
		    false, false, true),
-
 
1699
	VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SURFACE, &vmw_cmd_invalid,
-
 
1700
		    false, false, true),
-
 
1701
	VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SURFACE, &vmw_cmd_bind_gb_surface,
-
 
1702
		    true, false, true),
-
 
1703
	VMW_CMD_DEF(SVGA_3D_CMD_COND_BIND_GB_SURFACE, &vmw_cmd_invalid,
-
 
1704
		    false, false, true),
-
 
1705
	VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_IMAGE, &vmw_cmd_update_gb_image,
-
 
1706
		    true, false, true),
-
 
1707
	VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SURFACE,
-
 
1708
		    &vmw_cmd_update_gb_surface, true, false, true),
-
 
1709
	VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE,
-
 
1710
		    &vmw_cmd_readback_gb_image, true, false, true),
-
 
1711
	VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_SURFACE,
-
 
1712
		    &vmw_cmd_readback_gb_surface, true, false, true),
-
 
1713
	VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE,
-
 
1714
		    &vmw_cmd_invalidate_gb_image, true, false, true),
-
 
1715
	VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_SURFACE,
-
 
1716
		    &vmw_cmd_invalidate_gb_surface, true, false, true),
-
 
1717
	VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_CONTEXT, &vmw_cmd_invalid,
-
 
1718
		    false, false, true),
-
 
1719
	VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_CONTEXT, &vmw_cmd_invalid,
-
 
1720
		    false, false, true),
-
 
1721
	VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_CONTEXT, &vmw_cmd_invalid,
-
 
1722
		    false, false, true),
-
 
1723
	VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_CONTEXT, &vmw_cmd_invalid,
-
 
1724
		    false, false, true),
-
 
1725
	VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT, &vmw_cmd_invalid,
-
 
1726
		    false, false, true),
-
 
1727
	VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SHADER, &vmw_cmd_invalid,
-
 
1728
		    false, false, true),
-
 
1729
	VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SHADER, &vmw_cmd_bind_gb_shader,
-
 
1730
		    true, false, true),
-
 
1731
	VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid,
-
 
1732
		    false, false, true),
-
 
1733
	VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid,
-
 
1734
		    false, false, false),
-
 
1735
	VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query,
-
 
1736
		    true, false, true),
-
 
1737
	VMW_CMD_DEF(SVGA_3D_CMD_END_GB_QUERY, &vmw_cmd_end_gb_query,
-
 
1738
		    true, false, true),
-
 
1739
	VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_GB_QUERY, &vmw_cmd_wait_gb_query,
-
 
1740
		    true, false, true),
-
 
1741
	VMW_CMD_DEF(SVGA_3D_CMD_NOP, &vmw_cmd_ok,
-
 
1742
		    true, false, true),
-
 
1743
	VMW_CMD_DEF(SVGA_3D_CMD_ENABLE_GART, &vmw_cmd_invalid,
-
 
1744
		    false, false, true),
-
 
1745
	VMW_CMD_DEF(SVGA_3D_CMD_DISABLE_GART, &vmw_cmd_invalid,
-
 
1746
		    false, false, true),
-
 
1747
	VMW_CMD_DEF(SVGA_3D_CMD_MAP_MOB_INTO_GART, &vmw_cmd_invalid,
-
 
1748
		    false, false, true),
-
 
1749
	VMW_CMD_DEF(SVGA_3D_CMD_UNMAP_GART_RANGE, &vmw_cmd_invalid,
-
 
1750
		    false, false, true),
-
 
1751
	VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET, &vmw_cmd_invalid,
-
 
1752
		    false, false, true),
-
 
1753
	VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET, &vmw_cmd_invalid,
-
 
1754
		    false, false, true),
-
 
1755
	VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SCREENTARGET, &vmw_cmd_invalid,
-
 
1756
		    false, false, true),
-
 
1757
	VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET, &vmw_cmd_invalid,
-
 
1758
		    false, false, true),
-
 
1759
	VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL, &vmw_cmd_invalid,
-
 
1760
		    false, false, true),
-
 
1761
	VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL, &vmw_cmd_invalid,
-
 
1762
		    false, false, true),
-
 
1763
	VMW_CMD_DEF(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE, &vmw_cmd_cid_check,
1087
	VMW_CMD_DEF(SVGA_3D_CMD_DEACTIVATE_SURFACE, &vmw_cmd_invalid),
1764
		    true, false, true)
1088
};
1765
};
1089
 
1766
 
1090
static int vmw_cmd_check(struct vmw_private *dev_priv,
1767
static int vmw_cmd_check(struct vmw_private *dev_priv,
1091
			 struct vmw_sw_context *sw_context,
1768
			 struct vmw_sw_context *sw_context,
1092
			 void *buf, uint32_t *size)
1769
			 void *buf, uint32_t *size)
1093
{
1770
{
1094
	uint32_t cmd_id;
1771
	uint32_t cmd_id;
1095
	uint32_t size_remaining = *size;
1772
	uint32_t size_remaining = *size;
1096
	SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
1773
	SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
1097
	int ret;
1774
	int ret;
-
 
1775
	const struct vmw_cmd_entry *entry;
-
 
1776
	bool gb = dev_priv->capabilities & SVGA_CAP_GBOBJECTS;
1098
 
1777
 
1099
	cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
1778
	cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
1100
	/* Handle any none 3D commands */
1779
	/* Handle any none 3D commands */
1101
	if (unlikely(cmd_id < SVGA_CMD_MAX))
1780
	if (unlikely(cmd_id < SVGA_CMD_MAX))
1102
		return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size);
1781
		return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size);
1103
 
1782
 
1104
 
1783
 
1105
	cmd_id = le32_to_cpu(header->id);
1784
	cmd_id = le32_to_cpu(header->id);
1106
	*size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader);
1785
	*size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader);
1107
 
1786
 
1108
	cmd_id -= SVGA_3D_CMD_BASE;
1787
	cmd_id -= SVGA_3D_CMD_BASE;
1109
	if (unlikely(*size > size_remaining))
1788
	if (unlikely(*size > size_remaining))
1110
		goto out_err;
1789
		goto out_invalid;
1111
 
1790
 
-
 
1791
	if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
-
 
1792
		goto out_invalid;
-
 
1793
 
-
 
1794
	entry = &vmw_cmd_entries[cmd_id];
-
 
1795
	if (unlikely(!entry->user_allow && !sw_context->kernel))
-
 
1796
		goto out_privileged;
-
 
1797
 
1112
	if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
1798
	if (unlikely(entry->gb_disable && gb))
-
 
1799
		goto out_old;
-
 
1800
 
-
 
1801
	if (unlikely(entry->gb_enable && !gb))
1113
		goto out_err;
1802
		goto out_new;
1114
 
1803
 
1115
	ret = vmw_cmd_funcs[cmd_id](dev_priv, sw_context, header);
1804
	ret = entry->func(dev_priv, sw_context, header);
1116
	if (unlikely(ret != 0))
1805
	if (unlikely(ret != 0))
-
 
1806
		goto out_invalid;
-
 
1807
 
-
 
1808
	return 0;
-
 
1809
out_invalid:
-
 
1810
	DRM_ERROR("Invalid SVGA3D command: %d\n",
-
 
1811
		  cmd_id + SVGA_3D_CMD_BASE);
-
 
1812
	return -EINVAL;
-
 
1813
out_privileged:
1117
		goto out_err;
1814
	DRM_ERROR("Privileged SVGA3D command: %d\n",
1118
 
1815
		  cmd_id + SVGA_3D_CMD_BASE);
-
 
1816
	return -EPERM;
-
 
1817
out_old:
-
 
1818
	DRM_ERROR("Deprecated (disallowed) SVGA3D command: %d\n",
-
 
1819
		  cmd_id + SVGA_3D_CMD_BASE);
1119
	return 0;
1820
	return -EINVAL;
1120
out_err:
1821
out_new:
1121
	DRM_ERROR("Illegal / Invalid SVGA3D command: %d\n",
1822
	DRM_ERROR("SVGA3D command: %d not supported by virtual hardware.\n",
1122
		  cmd_id + SVGA_3D_CMD_BASE);
1823
		  cmd_id + SVGA_3D_CMD_BASE);
1123
	return -EINVAL;
1824
	return -EINVAL;
1124
}
1825
}
1125
 
1826
 
1126
static int vmw_cmd_check_all(struct vmw_private *dev_priv,
1827
static int vmw_cmd_check_all(struct vmw_private *dev_priv,
1127
			     struct vmw_sw_context *sw_context,
1828
			     struct vmw_sw_context *sw_context,
1128
			     void *buf,
1829
			     void *buf,
1129
			     uint32_t size)
1830
			     uint32_t size)
1130
{
1831
{
1131
	int32_t cur_size = size;
1832
	int32_t cur_size = size;
1132
	int ret;
1833
	int ret;
1133
 
1834
 
1134
	sw_context->buf_start = buf;
1835
	sw_context->buf_start = buf;
1135
 
1836
 
1136
	while (cur_size > 0) {
1837
	while (cur_size > 0) {
1137
		size = cur_size;
1838
		size = cur_size;
1138
		ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
1839
		ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
1139
		if (unlikely(ret != 0))
1840
		if (unlikely(ret != 0))
1140
			return ret;
1841
			return ret;
1141
		buf = (void *)((unsigned long) buf + size);
1842
		buf = (void *)((unsigned long) buf + size);
1142
		cur_size -= size;
1843
		cur_size -= size;
1143
	}
1844
	}
1144
 
1845
 
1145
	if (unlikely(cur_size != 0)) {
1846
	if (unlikely(cur_size != 0)) {
1146
		DRM_ERROR("Command verifier out of sync.\n");
1847
		DRM_ERROR("Command verifier out of sync.\n");
1147
		return -EINVAL;
1848
		return -EINVAL;
1148
	}
1849
	}
1149
 
1850
 
1150
	return 0;
1851
	return 0;
1151
}
1852
}
1152
 
1853
 
1153
static void vmw_free_relocations(struct vmw_sw_context *sw_context)
1854
static void vmw_free_relocations(struct vmw_sw_context *sw_context)
1154
{
1855
{
1155
	sw_context->cur_reloc = 0;
1856
	sw_context->cur_reloc = 0;
1156
}
1857
}
1157
 
1858
 
1158
static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
1859
static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
1159
{
1860
{
1160
	uint32_t i;
1861
	uint32_t i;
1161
	struct vmw_relocation *reloc;
1862
	struct vmw_relocation *reloc;
1162
	struct ttm_validate_buffer *validate;
1863
	struct ttm_validate_buffer *validate;
1163
	struct ttm_buffer_object *bo;
1864
	struct ttm_buffer_object *bo;
1164
 
1865
 
1165
	for (i = 0; i < sw_context->cur_reloc; ++i) {
1866
	for (i = 0; i < sw_context->cur_reloc; ++i) {
1166
		reloc = &sw_context->relocs[i];
1867
		reloc = &sw_context->relocs[i];
1167
		validate = &sw_context->val_bufs[reloc->index].base;
1868
		validate = &sw_context->val_bufs[reloc->index].base;
1168
		bo = validate->bo;
1869
		bo = validate->bo;
1169
		switch (bo->mem.mem_type) {
1870
		switch (bo->mem.mem_type) {
1170
		case TTM_PL_VRAM:
1871
		case TTM_PL_VRAM:
1171
			reloc->location->offset += bo->offset;
1872
			reloc->location->offset += bo->offset;
1172
			reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER;
1873
			reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER;
1173
			break;
1874
			break;
1174
		case VMW_PL_GMR:
1875
		case VMW_PL_GMR:
1175
			reloc->location->gmrId = bo->mem.start;
1876
			reloc->location->gmrId = bo->mem.start;
1176
			break;
1877
			break;
-
 
1878
		case VMW_PL_MOB:
-
 
1879
			*reloc->mob_loc = bo->mem.start;
-
 
1880
			break;
1177
		default:
1881
		default:
1178
			BUG();
1882
			BUG();
1179
		}
1883
		}
1180
	}
1884
	}
1181
	vmw_free_relocations(sw_context);
1885
	vmw_free_relocations(sw_context);
1182
}
1886
}
1183
 
1887
 
1184
/**
1888
/**
1185
 * vmw_resource_list_unrefererence - Free up a resource list and unreference
1889
 * vmw_resource_list_unrefererence - Free up a resource list and unreference
1186
 * all resources referenced by it.
1890
 * all resources referenced by it.
1187
 *
1891
 *
1188
 * @list: The resource list.
1892
 * @list: The resource list.
1189
 */
1893
 */
1190
static void vmw_resource_list_unreference(struct list_head *list)
1894
static void vmw_resource_list_unreference(struct list_head *list)
1191
{
1895
{
1192
	struct vmw_resource_val_node *val, *val_next;
1896
	struct vmw_resource_val_node *val, *val_next;
1193
 
1897
 
1194
	/*
1898
	/*
1195
	 * Drop references to resources held during command submission.
1899
	 * Drop references to resources held during command submission.
1196
	 */
1900
	 */
1197
 
1901
 
1198
	list_for_each_entry_safe(val, val_next, list, head) {
1902
	list_for_each_entry_safe(val, val_next, list, head) {
1199
		list_del_init(&val->head);
1903
		list_del_init(&val->head);
1200
		vmw_resource_unreference(&val->res);
1904
		vmw_resource_unreference(&val->res);
-
 
1905
		if (unlikely(val->staged_bindings))
-
 
1906
			kfree(val->staged_bindings);
1201
		kfree(val);
1907
		kfree(val);
1202
	}
1908
	}
1203
}
1909
}
1204
 
1910
 
1205
static void vmw_clear_validations(struct vmw_sw_context *sw_context)
1911
static void vmw_clear_validations(struct vmw_sw_context *sw_context)
1206
{
1912
{
1207
	struct vmw_validate_buffer *entry, *next;
1913
	struct vmw_validate_buffer *entry, *next;
1208
	struct vmw_resource_val_node *val;
1914
	struct vmw_resource_val_node *val;
1209
 
1915
 
1210
	/*
1916
	/*
1211
	 * Drop references to DMA buffers held during command submission.
1917
	 * Drop references to DMA buffers held during command submission.
1212
	 */
1918
	 */
1213
	list_for_each_entry_safe(entry, next, &sw_context->validate_nodes,
1919
	list_for_each_entry_safe(entry, next, &sw_context->validate_nodes,
1214
				 base.head) {
1920
				 base.head) {
1215
		list_del(&entry->base.head);
1921
		list_del(&entry->base.head);
1216
		ttm_bo_unref(&entry->base.bo);
1922
		ttm_bo_unref(&entry->base.bo);
1217
		(void) drm_ht_remove_item(&sw_context->res_ht, &entry->hash);
1923
		(void) drm_ht_remove_item(&sw_context->res_ht, &entry->hash);
1218
		sw_context->cur_val_buf--;
1924
		sw_context->cur_val_buf--;
1219
	}
1925
	}
1220
	BUG_ON(sw_context->cur_val_buf != 0);
1926
	BUG_ON(sw_context->cur_val_buf != 0);
1221
 
1927
 
1222
	list_for_each_entry(val, &sw_context->resource_list, head)
1928
	list_for_each_entry(val, &sw_context->resource_list, head)
1223
		(void) drm_ht_remove_item(&sw_context->res_ht, &val->hash);
1929
		(void) drm_ht_remove_item(&sw_context->res_ht, &val->hash);
1224
}
1930
}
1225
 
1931
 
1226
static int vmw_validate_single_buffer(struct vmw_private *dev_priv,
1932
static int vmw_validate_single_buffer(struct vmw_private *dev_priv,
1227
				      struct ttm_buffer_object *bo)
1933
				      struct ttm_buffer_object *bo,
-
 
1934
				      bool validate_as_mob)
1228
{
1935
{
1229
	int ret;
1936
	int ret;
1230
 
1937
 
1231
 
1938
 
1232
	/*
1939
	/*
1233
	 * Don't validate pinned buffers.
1940
	 * Don't validate pinned buffers.
1234
	 */
1941
	 */
1235
 
1942
 
1236
	if (bo == dev_priv->pinned_bo ||
1943
	if (bo == dev_priv->pinned_bo ||
1237
	    (bo == dev_priv->dummy_query_bo &&
1944
	    (bo == dev_priv->dummy_query_bo &&
1238
	     dev_priv->dummy_query_bo_pinned))
1945
	     dev_priv->dummy_query_bo_pinned))
1239
		return 0;
1946
		return 0;
-
 
1947
 
-
 
1948
	if (validate_as_mob)
-
 
1949
		return ttm_bo_validate(bo, &vmw_mob_placement, true, false);
1240
 
1950
 
1241
	/**
1951
	/**
1242
	 * Put BO in VRAM if there is space, otherwise as a GMR.
1952
	 * Put BO in VRAM if there is space, otherwise as a GMR.
1243
	 * If there is no space in VRAM and GMR ids are all used up,
1953
	 * If there is no space in VRAM and GMR ids are all used up,
1244
	 * start evicting GMRs to make room. If the DMA buffer can't be
1954
	 * start evicting GMRs to make room. If the DMA buffer can't be
1245
	 * used as a GMR, this will return -ENOMEM.
1955
	 * used as a GMR, this will return -ENOMEM.
1246
	 */
1956
	 */
1247
 
1957
 
1248
	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, true, false);
1958
	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, true, false);
1249
	if (likely(ret == 0 || ret == -ERESTARTSYS))
1959
	if (likely(ret == 0 || ret == -ERESTARTSYS))
1250
		return ret;
1960
		return ret;
1251
 
1961
 
1252
	/**
1962
	/**
1253
	 * If that failed, try VRAM again, this time evicting
1963
	 * If that failed, try VRAM again, this time evicting
1254
	 * previous contents.
1964
	 * previous contents.
1255
	 */
1965
	 */
1256
 
1966
 
1257
	DRM_INFO("Falling through to VRAM.\n");
1967
	DRM_INFO("Falling through to VRAM.\n");
1258
	ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false);
1968
	ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false);
1259
	return ret;
1969
	return ret;
1260
}
1970
}
1261
 
-
 
1262
 
1971
 
1263
static int vmw_validate_buffers(struct vmw_private *dev_priv,
1972
static int vmw_validate_buffers(struct vmw_private *dev_priv,
1264
				struct vmw_sw_context *sw_context)
1973
				struct vmw_sw_context *sw_context)
1265
{
1974
{
1266
	struct vmw_validate_buffer *entry;
1975
	struct vmw_validate_buffer *entry;
1267
	int ret;
1976
	int ret;
1268
 
1977
 
1269
	list_for_each_entry(entry, &sw_context->validate_nodes, base.head) {
1978
	list_for_each_entry(entry, &sw_context->validate_nodes, base.head) {
1270
		ret = vmw_validate_single_buffer(dev_priv, entry->base.bo);
1979
		ret = vmw_validate_single_buffer(dev_priv, entry->base.bo,
-
 
1980
						 entry->validate_as_mob);
1271
		if (unlikely(ret != 0))
1981
		if (unlikely(ret != 0))
1272
			return ret;
1982
			return ret;
1273
	}
1983
	}
1274
	return 0;
1984
	return 0;
1275
}
1985
}
1276
 
1986
 
1277
static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context,
1987
static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context,
1278
				 uint32_t size)
1988
				 uint32_t size)
1279
{
1989
{
1280
	if (likely(sw_context->cmd_bounce_size >= size))
1990
	if (likely(sw_context->cmd_bounce_size >= size))
1281
		return 0;
1991
		return 0;
1282
 
1992
 
1283
	if (sw_context->cmd_bounce_size == 0)
1993
	if (sw_context->cmd_bounce_size == 0)
1284
		sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE;
1994
		sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE;
1285
 
1995
 
1286
	while (sw_context->cmd_bounce_size < size) {
1996
	while (sw_context->cmd_bounce_size < size) {
1287
		sw_context->cmd_bounce_size =
1997
		sw_context->cmd_bounce_size =
1288
			PAGE_ALIGN(sw_context->cmd_bounce_size +
1998
			PAGE_ALIGN(sw_context->cmd_bounce_size +
1289
				   (sw_context->cmd_bounce_size >> 1));
1999
				   (sw_context->cmd_bounce_size >> 1));
1290
	}
2000
	}
1291
 
2001
 
1292
	if (sw_context->cmd_bounce != NULL)
2002
	if (sw_context->cmd_bounce != NULL)
1293
		vfree(sw_context->cmd_bounce);
2003
		vfree(sw_context->cmd_bounce);
1294
 
2004
 
1295
    sw_context->cmd_bounce = KernelAlloc(sw_context->cmd_bounce_size);
2005
	sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size);
1296
 
2006
 
1297
	if (sw_context->cmd_bounce == NULL) {
2007
	if (sw_context->cmd_bounce == NULL) {
1298
		DRM_ERROR("Failed to allocate command bounce buffer.\n");
2008
		DRM_ERROR("Failed to allocate command bounce buffer.\n");
1299
		sw_context->cmd_bounce_size = 0;
2009
		sw_context->cmd_bounce_size = 0;
1300
		return -ENOMEM;
2010
		return -ENOMEM;
1301
	}
2011
	}
1302
 
2012
 
1303
	return 0;
2013
	return 0;
1304
}
2014
}
1305
 
2015
 
1306
/**
2016
/**
1307
 * vmw_execbuf_fence_commands - create and submit a command stream fence
2017
 * vmw_execbuf_fence_commands - create and submit a command stream fence
1308
 *
2018
 *
1309
 * Creates a fence object and submits a command stream marker.
2019
 * Creates a fence object and submits a command stream marker.
1310
 * If this fails for some reason, We sync the fifo and return NULL.
2020
 * If this fails for some reason, We sync the fifo and return NULL.
1311
 * It is then safe to fence buffers with a NULL pointer.
2021
 * It is then safe to fence buffers with a NULL pointer.
1312
 *
2022
 *
1313
 * If @p_handle is not NULL @file_priv must also not be NULL. Creates
2023
 * If @p_handle is not NULL @file_priv must also not be NULL. Creates
1314
 * a userspace handle if @p_handle is not NULL, otherwise not.
2024
 * a userspace handle if @p_handle is not NULL, otherwise not.
1315
 */
2025
 */
1316
 
2026
 
1317
int vmw_execbuf_fence_commands(struct drm_file *file_priv,
2027
int vmw_execbuf_fence_commands(struct drm_file *file_priv,
1318
			       struct vmw_private *dev_priv,
2028
			       struct vmw_private *dev_priv,
1319
			       struct vmw_fence_obj **p_fence,
2029
			       struct vmw_fence_obj **p_fence,
1320
			       uint32_t *p_handle)
2030
			       uint32_t *p_handle)
1321
{
2031
{
1322
	uint32_t sequence;
2032
	uint32_t sequence;
1323
	int ret;
2033
	int ret;
1324
	bool synced = false;
2034
	bool synced = false;
1325
 
2035
 
1326
	/* p_handle implies file_priv. */
2036
	/* p_handle implies file_priv. */
1327
	BUG_ON(p_handle != NULL && file_priv == NULL);
2037
	BUG_ON(p_handle != NULL && file_priv == NULL);
1328
 
2038
 
1329
	ret = vmw_fifo_send_fence(dev_priv, &sequence);
2039
	ret = vmw_fifo_send_fence(dev_priv, &sequence);
1330
	if (unlikely(ret != 0)) {
2040
	if (unlikely(ret != 0)) {
1331
		DRM_ERROR("Fence submission error. Syncing.\n");
2041
		DRM_ERROR("Fence submission error. Syncing.\n");
1332
		synced = true;
2042
		synced = true;
1333
	}
2043
	}
1334
 
2044
 
1335
	if (p_handle != NULL)
2045
	if (p_handle != NULL)
1336
		ret = vmw_user_fence_create(file_priv, dev_priv->fman,
2046
		ret = vmw_user_fence_create(file_priv, dev_priv->fman,
1337
					    sequence,
2047
					    sequence,
1338
					    DRM_VMW_FENCE_FLAG_EXEC,
2048
					    DRM_VMW_FENCE_FLAG_EXEC,
1339
					    p_fence, p_handle);
2049
					    p_fence, p_handle);
1340
	else
2050
	else
1341
		ret = vmw_fence_create(dev_priv->fman, sequence,
2051
		ret = vmw_fence_create(dev_priv->fman, sequence,
1342
				       DRM_VMW_FENCE_FLAG_EXEC,
2052
				       DRM_VMW_FENCE_FLAG_EXEC,
1343
				       p_fence);
2053
				       p_fence);
1344
 
2054
 
1345
	if (unlikely(ret != 0 && !synced)) {
2055
	if (unlikely(ret != 0 && !synced)) {
1346
		(void) vmw_fallback_wait(dev_priv, false, false,
2056
		(void) vmw_fallback_wait(dev_priv, false, false,
1347
					 sequence, false,
2057
					 sequence, false,
1348
					 VMW_FENCE_WAIT_TIMEOUT);
2058
					 VMW_FENCE_WAIT_TIMEOUT);
1349
		*p_fence = NULL;
2059
		*p_fence = NULL;
1350
	}
2060
	}
1351
 
2061
 
1352
	return 0;
2062
	return 0;
1353
}
2063
}
1354
 
2064
 
1355
/**
2065
/**
1356
 * vmw_execbuf_copy_fence_user - copy fence object information to
2066
 * vmw_execbuf_copy_fence_user - copy fence object information to
1357
 * user-space.
2067
 * user-space.
1358
 *
2068
 *
1359
 * @dev_priv: Pointer to a vmw_private struct.
2069
 * @dev_priv: Pointer to a vmw_private struct.
1360
 * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file.
2070
 * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file.
1361
 * @ret: Return value from fence object creation.
2071
 * @ret: Return value from fence object creation.
1362
 * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to
2072
 * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to
1363
 * which the information should be copied.
2073
 * which the information should be copied.
1364
 * @fence: Pointer to the fenc object.
2074
 * @fence: Pointer to the fenc object.
1365
 * @fence_handle: User-space fence handle.
2075
 * @fence_handle: User-space fence handle.
1366
 *
2076
 *
1367
 * This function copies fence information to user-space. If copying fails,
2077
 * This function copies fence information to user-space. If copying fails,
1368
 * The user-space struct drm_vmw_fence_rep::error member is hopefully
2078
 * The user-space struct drm_vmw_fence_rep::error member is hopefully
1369
 * left untouched, and if it's preloaded with an -EFAULT by user-space,
2079
 * left untouched, and if it's preloaded with an -EFAULT by user-space,
1370
 * the error will hopefully be detected.
2080
 * the error will hopefully be detected.
1371
 * Also if copying fails, user-space will be unable to signal the fence
2081
 * Also if copying fails, user-space will be unable to signal the fence
1372
 * object so we wait for it immediately, and then unreference the
2082
 * object so we wait for it immediately, and then unreference the
1373
 * user-space reference.
2083
 * user-space reference.
1374
 */
2084
 */
1375
void
2085
void
1376
vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
2086
vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
1377
			    struct vmw_fpriv *vmw_fp,
2087
			    struct vmw_fpriv *vmw_fp,
1378
			    int ret,
2088
			    int ret,
1379
			    struct drm_vmw_fence_rep __user *user_fence_rep,
2089
			    struct drm_vmw_fence_rep __user *user_fence_rep,
1380
			    struct vmw_fence_obj *fence,
2090
			    struct vmw_fence_obj *fence,
1381
			    uint32_t fence_handle)
2091
			    uint32_t fence_handle)
1382
{
2092
{
1383
	struct drm_vmw_fence_rep fence_rep;
2093
	struct drm_vmw_fence_rep fence_rep;
1384
 
2094
 
1385
	if (user_fence_rep == NULL)
2095
	if (user_fence_rep == NULL)
1386
		return;
2096
		return;
1387
 
2097
 
1388
	memset(&fence_rep, 0, sizeof(fence_rep));
2098
	memset(&fence_rep, 0, sizeof(fence_rep));
1389
 
2099
 
1390
	fence_rep.error = ret;
2100
	fence_rep.error = ret;
1391
	if (ret == 0) {
2101
	if (ret == 0) {
1392
		BUG_ON(fence == NULL);
2102
		BUG_ON(fence == NULL);
1393
 
2103
 
1394
		fence_rep.handle = fence_handle;
2104
		fence_rep.handle = fence_handle;
1395
		fence_rep.seqno = fence->seqno;
2105
		fence_rep.seqno = fence->seqno;
1396
		vmw_update_seqno(dev_priv, &dev_priv->fifo);
2106
		vmw_update_seqno(dev_priv, &dev_priv->fifo);
1397
		fence_rep.passed_seqno = dev_priv->last_read_seqno;
2107
		fence_rep.passed_seqno = dev_priv->last_read_seqno;
1398
	}
2108
	}
1399
 
2109
 
1400
	/*
2110
	/*
1401
	 * copy_to_user errors will be detected by user space not
2111
	 * copy_to_user errors will be detected by user space not
1402
	 * seeing fence_rep::error filled in. Typically
2112
	 * seeing fence_rep::error filled in. Typically
1403
	 * user-space would have pre-set that member to -EFAULT.
2113
	 * user-space would have pre-set that member to -EFAULT.
1404
	 */
2114
	 */
1405
//   ret = copy_to_user(user_fence_rep, &fence_rep,
2115
//   ret = copy_to_user(user_fence_rep, &fence_rep,
1406
//              sizeof(fence_rep));
2116
//              sizeof(fence_rep));
1407
 
2117
 
1408
	/*
2118
	/*
1409
	 * User-space lost the fence object. We need to sync
2119
	 * User-space lost the fence object. We need to sync
1410
	 * and unreference the handle.
2120
	 * and unreference the handle.
1411
	 */
2121
	 */
1412
	if (unlikely(ret != 0) && (fence_rep.error == 0)) {
2122
	if (unlikely(ret != 0) && (fence_rep.error == 0)) {
1413
		ttm_ref_object_base_unref(vmw_fp->tfile,
2123
		ttm_ref_object_base_unref(vmw_fp->tfile,
1414
					  fence_handle, TTM_REF_USAGE);
2124
					  fence_handle, TTM_REF_USAGE);
1415
		DRM_ERROR("Fence copy error. Syncing.\n");
2125
		DRM_ERROR("Fence copy error. Syncing.\n");
1416
		(void) vmw_fence_obj_wait(fence, fence->signal_mask,
2126
		(void) vmw_fence_obj_wait(fence, fence->signal_mask,
1417
					  false, false,
2127
					  false, false,
1418
					  VMW_FENCE_WAIT_TIMEOUT);
2128
					  VMW_FENCE_WAIT_TIMEOUT);
1419
	}
2129
	}
1420
}
2130
}
1421
 
2131
 
1422
int vmw_execbuf_process(struct drm_file *file_priv,
2132
int vmw_execbuf_process(struct drm_file *file_priv,
1423
			struct vmw_private *dev_priv,
2133
			struct vmw_private *dev_priv,
1424
			void __user *user_commands,
2134
			void __user *user_commands,
1425
			void *kernel_commands,
2135
			void *kernel_commands,
1426
			uint32_t command_size,
2136
			uint32_t command_size,
1427
			uint64_t throttle_us,
2137
			uint64_t throttle_us,
1428
			struct drm_vmw_fence_rep __user *user_fence_rep,
2138
			struct drm_vmw_fence_rep __user *user_fence_rep,
1429
			struct vmw_fence_obj **out_fence)
2139
			struct vmw_fence_obj **out_fence)
1430
{
2140
{
1431
	struct vmw_sw_context *sw_context = &dev_priv->ctx;
2141
	struct vmw_sw_context *sw_context = &dev_priv->ctx;
1432
	struct vmw_fence_obj *fence = NULL;
2142
	struct vmw_fence_obj *fence = NULL;
1433
	struct vmw_resource *error_resource;
2143
	struct vmw_resource *error_resource;
1434
	struct list_head resource_list;
2144
	struct list_head resource_list;
1435
	struct ww_acquire_ctx ticket;
2145
	struct ww_acquire_ctx ticket;
1436
	uint32_t handle;
2146
	uint32_t handle;
1437
	void *cmd;
2147
	void *cmd;
1438
	int ret;
2148
	int ret;
1439
 
2149
 
1440
	ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
2150
	ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
1441
	if (unlikely(ret != 0))
2151
	if (unlikely(ret != 0))
1442
		return -ERESTARTSYS;
2152
		return -ERESTARTSYS;
1443
 
2153
 
1444
/*
2154
/*
1445
	if (kernel_commands == NULL) {
2155
	if (kernel_commands == NULL) {
1446
		sw_context->kernel = false;
2156
		sw_context->kernel = false;
1447
 
2157
 
1448
		ret = vmw_resize_cmd_bounce(sw_context, command_size);
2158
		ret = vmw_resize_cmd_bounce(sw_context, command_size);
1449
		if (unlikely(ret != 0))
2159
		if (unlikely(ret != 0))
1450
			goto out_unlock;
2160
			goto out_unlock;
1451
 
2161
 
1452
 
2162
 
1453
		ret = copy_from_user(sw_context->cmd_bounce,
2163
		ret = copy_from_user(sw_context->cmd_bounce,
1454
				     user_commands, command_size);
2164
				     user_commands, command_size);
1455
 
2165
 
1456
		if (unlikely(ret != 0)) {
2166
		if (unlikely(ret != 0)) {
1457
			ret = -EFAULT;
2167
			ret = -EFAULT;
1458
			DRM_ERROR("Failed copying commands.\n");
2168
			DRM_ERROR("Failed copying commands.\n");
1459
			goto out_unlock;
2169
			goto out_unlock;
1460
		}
2170
		}
1461
		kernel_commands = sw_context->cmd_bounce;
2171
		kernel_commands = sw_context->cmd_bounce;
1462
    } else  */
2172
    } else  */
1463
		sw_context->kernel = true;
2173
		sw_context->kernel = true;
1464
 
2174
 
1465
	sw_context->tfile = vmw_fpriv(file_priv)->tfile;
2175
	sw_context->tfile = vmw_fpriv(file_priv)->tfile;
1466
	sw_context->cur_reloc = 0;
2176
	sw_context->cur_reloc = 0;
1467
	sw_context->cur_val_buf = 0;
2177
	sw_context->cur_val_buf = 0;
1468
	sw_context->fence_flags = 0;
2178
	sw_context->fence_flags = 0;
1469
	INIT_LIST_HEAD(&sw_context->resource_list);
2179
	INIT_LIST_HEAD(&sw_context->resource_list);
1470
	sw_context->cur_query_bo = dev_priv->pinned_bo;
2180
	sw_context->cur_query_bo = dev_priv->pinned_bo;
1471
	sw_context->last_query_ctx = NULL;
2181
	sw_context->last_query_ctx = NULL;
1472
	sw_context->needs_post_query_barrier = false;
2182
	sw_context->needs_post_query_barrier = false;
1473
	memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache));
2183
	memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache));
1474
	INIT_LIST_HEAD(&sw_context->validate_nodes);
2184
	INIT_LIST_HEAD(&sw_context->validate_nodes);
1475
	INIT_LIST_HEAD(&sw_context->res_relocations);
2185
	INIT_LIST_HEAD(&sw_context->res_relocations);
1476
	if (!sw_context->res_ht_initialized) {
2186
	if (!sw_context->res_ht_initialized) {
1477
		ret = drm_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER);
2187
		ret = drm_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER);
1478
		if (unlikely(ret != 0))
2188
		if (unlikely(ret != 0))
1479
			goto out_unlock;
2189
			goto out_unlock;
1480
		sw_context->res_ht_initialized = true;
2190
		sw_context->res_ht_initialized = true;
1481
	}
2191
	}
1482
 
2192
 
1483
	INIT_LIST_HEAD(&resource_list);
2193
	INIT_LIST_HEAD(&resource_list);
1484
	ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
2194
	ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
1485
				command_size);
2195
				command_size);
1486
	if (unlikely(ret != 0))
2196
	if (unlikely(ret != 0))
1487
		goto out_err;
2197
		goto out_err;
1488
 
2198
 
1489
	ret = vmw_resources_reserve(sw_context);
2199
	ret = vmw_resources_reserve(sw_context);
1490
	if (unlikely(ret != 0))
2200
	if (unlikely(ret != 0))
1491
		goto out_err;
2201
		goto out_err;
1492
 
2202
 
1493
	ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes);
2203
	ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes);
1494
	if (unlikely(ret != 0))
2204
	if (unlikely(ret != 0))
1495
		goto out_err;
2205
		goto out_err;
1496
 
2206
 
1497
	ret = vmw_validate_buffers(dev_priv, sw_context);
2207
	ret = vmw_validate_buffers(dev_priv, sw_context);
1498
	if (unlikely(ret != 0))
2208
	if (unlikely(ret != 0))
1499
		goto out_err;
2209
		goto out_err;
1500
 
2210
 
1501
	ret = vmw_resources_validate(sw_context);
2211
	ret = vmw_resources_validate(sw_context);
1502
	if (unlikely(ret != 0))
2212
	if (unlikely(ret != 0))
1503
		goto out_err;
2213
		goto out_err;
1504
 
2214
 
1505
	if (throttle_us) {
2215
	if (throttle_us) {
1506
		ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
2216
		ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
1507
				   throttle_us);
2217
				   throttle_us);
1508
 
2218
 
1509
		if (unlikely(ret != 0))
2219
		if (unlikely(ret != 0))
1510
			goto out_err;
2220
			goto out_err;
1511
	}
2221
	}
-
 
2222
 
-
 
2223
	ret = mutex_lock_interruptible(&dev_priv->binding_mutex);
-
 
2224
	if (unlikely(ret != 0)) {
-
 
2225
		ret = -ERESTARTSYS;
-
 
2226
		goto out_err;
-
 
2227
	}
1512
 
2228
 
1513
	cmd = vmw_fifo_reserve(dev_priv, command_size);
2229
	cmd = vmw_fifo_reserve(dev_priv, command_size);
1514
	if (unlikely(cmd == NULL)) {
2230
	if (unlikely(cmd == NULL)) {
1515
		DRM_ERROR("Failed reserving fifo space for commands.\n");
2231
		DRM_ERROR("Failed reserving fifo space for commands.\n");
1516
		ret = -ENOMEM;
2232
		ret = -ENOMEM;
1517
		goto out_err;
2233
		goto out_unlock_binding;
1518
	}
2234
	}
1519
 
2235
 
1520
	vmw_apply_relocations(sw_context);
2236
	vmw_apply_relocations(sw_context);
1521
	memcpy(cmd, kernel_commands, command_size);
2237
	memcpy(cmd, kernel_commands, command_size);
1522
 
2238
 
1523
	vmw_resource_relocations_apply(cmd, &sw_context->res_relocations);
2239
	vmw_resource_relocations_apply(cmd, &sw_context->res_relocations);
1524
	vmw_resource_relocations_free(&sw_context->res_relocations);
2240
	vmw_resource_relocations_free(&sw_context->res_relocations);
1525
 
2241
 
1526
	vmw_fifo_commit(dev_priv, command_size);
2242
	vmw_fifo_commit(dev_priv, command_size);
1527
 
2243
 
1528
	vmw_query_bo_switch_commit(dev_priv, sw_context);
2244
	vmw_query_bo_switch_commit(dev_priv, sw_context);
1529
	ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
2245
	ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
1530
					 &fence,
2246
					 &fence,
1531
					 (user_fence_rep) ? &handle : NULL);
2247
					 (user_fence_rep) ? &handle : NULL);
1532
	/*
2248
	/*
1533
	 * This error is harmless, because if fence submission fails,
2249
	 * This error is harmless, because if fence submission fails,
1534
	 * vmw_fifo_send_fence will sync. The error will be propagated to
2250
	 * vmw_fifo_send_fence will sync. The error will be propagated to
1535
	 * user-space in @fence_rep
2251
	 * user-space in @fence_rep
1536
	 */
2252
	 */
1537
 
2253
 
1538
	if (ret != 0)
2254
	if (ret != 0)
1539
		DRM_ERROR("Fence submission error. Syncing.\n");
2255
		DRM_ERROR("Fence submission error. Syncing.\n");
1540
 
2256
 
1541
	vmw_resource_list_unreserve(&sw_context->resource_list, false);
2257
	vmw_resource_list_unreserve(&sw_context->resource_list, false);
-
 
2258
	mutex_unlock(&dev_priv->binding_mutex);
-
 
2259
 
1542
	ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes,
2260
	ttm_eu_fence_buffer_objects(&ticket, &sw_context->validate_nodes,
1543
				    (void *) fence);
2261
				    (void *) fence);
1544
 
2262
 
1545
	if (unlikely(dev_priv->pinned_bo != NULL &&
2263
	if (unlikely(dev_priv->pinned_bo != NULL &&
1546
		     !dev_priv->query_cid_valid))
2264
		     !dev_priv->query_cid_valid))
1547
		__vmw_execbuf_release_pinned_bo(dev_priv, fence);
2265
		__vmw_execbuf_release_pinned_bo(dev_priv, fence);
1548
 
2266
 
1549
	vmw_clear_validations(sw_context);
2267
	vmw_clear_validations(sw_context);
1550
	vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
2268
	vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
1551
				    user_fence_rep, fence, handle);
2269
				    user_fence_rep, fence, handle);
1552
 
2270
 
1553
	/* Don't unreference when handing fence out */
2271
	/* Don't unreference when handing fence out */
1554
	if (unlikely(out_fence != NULL)) {
2272
	if (unlikely(out_fence != NULL)) {
1555
		*out_fence = fence;
2273
		*out_fence = fence;
1556
		fence = NULL;
2274
		fence = NULL;
1557
	} else if (likely(fence != NULL)) {
2275
	} else if (likely(fence != NULL)) {
1558
		vmw_fence_obj_unreference(&fence);
2276
		vmw_fence_obj_unreference(&fence);
1559
	}
2277
	}
1560
 
2278
 
1561
	list_splice_init(&sw_context->resource_list, &resource_list);
2279
	list_splice_init(&sw_context->resource_list, &resource_list);
1562
	mutex_unlock(&dev_priv->cmdbuf_mutex);
2280
	mutex_unlock(&dev_priv->cmdbuf_mutex);
1563
 
2281
 
1564
	/*
2282
	/*
1565
	 * Unreference resources outside of the cmdbuf_mutex to
2283
	 * Unreference resources outside of the cmdbuf_mutex to
1566
	 * avoid deadlocks in resource destruction paths.
2284
	 * avoid deadlocks in resource destruction paths.
1567
	 */
2285
	 */
1568
	vmw_resource_list_unreference(&resource_list);
2286
	vmw_resource_list_unreference(&resource_list);
1569
 
2287
 
1570
	return 0;
2288
	return 0;
-
 
2289
 
-
 
2290
out_unlock_binding:
1571
 
2291
	mutex_unlock(&dev_priv->binding_mutex);
1572
out_err:
2292
out_err:
1573
	vmw_resource_relocations_free(&sw_context->res_relocations);
2293
	vmw_resource_relocations_free(&sw_context->res_relocations);
1574
	vmw_free_relocations(sw_context);
2294
	vmw_free_relocations(sw_context);
1575
	ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes);
2295
	ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes);
1576
	vmw_resource_list_unreserve(&sw_context->resource_list, true);
2296
	vmw_resource_list_unreserve(&sw_context->resource_list, true);
1577
	vmw_clear_validations(sw_context);
2297
	vmw_clear_validations(sw_context);
1578
	if (unlikely(dev_priv->pinned_bo != NULL &&
2298
	if (unlikely(dev_priv->pinned_bo != NULL &&
1579
		     !dev_priv->query_cid_valid))
2299
		     !dev_priv->query_cid_valid))
1580
		__vmw_execbuf_release_pinned_bo(dev_priv, NULL);
2300
		__vmw_execbuf_release_pinned_bo(dev_priv, NULL);
1581
out_unlock:
2301
out_unlock:
1582
	list_splice_init(&sw_context->resource_list, &resource_list);
2302
	list_splice_init(&sw_context->resource_list, &resource_list);
1583
	error_resource = sw_context->error_resource;
2303
	error_resource = sw_context->error_resource;
1584
	sw_context->error_resource = NULL;
2304
	sw_context->error_resource = NULL;
1585
	mutex_unlock(&dev_priv->cmdbuf_mutex);
2305
	mutex_unlock(&dev_priv->cmdbuf_mutex);
1586
 
2306
 
1587
	/*
2307
	/*
1588
	 * Unreference resources outside of the cmdbuf_mutex to
2308
	 * Unreference resources outside of the cmdbuf_mutex to
1589
	 * avoid deadlocks in resource destruction paths.
2309
	 * avoid deadlocks in resource destruction paths.
1590
	 */
2310
	 */
1591
	vmw_resource_list_unreference(&resource_list);
2311
	vmw_resource_list_unreference(&resource_list);
1592
	if (unlikely(error_resource != NULL))
2312
	if (unlikely(error_resource != NULL))
1593
		vmw_resource_unreference(&error_resource);
2313
		vmw_resource_unreference(&error_resource);
1594
 
2314
 
1595
	return ret;
2315
	return ret;
1596
}
2316
}
1597
 
2317
 
1598
/**
2318
/**
1599
 * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
2319
 * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
1600
 *
2320
 *
1601
 * @dev_priv: The device private structure.
2321
 * @dev_priv: The device private structure.
1602
 *
2322
 *
1603
 * This function is called to idle the fifo and unpin the query buffer
2323
 * This function is called to idle the fifo and unpin the query buffer
1604
 * if the normal way to do this hits an error, which should typically be
2324
 * if the normal way to do this hits an error, which should typically be
1605
 * extremely rare.
2325
 * extremely rare.
1606
 */
2326
 */
1607
static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv)
2327
static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv)
1608
{
2328
{
1609
	DRM_ERROR("Can't unpin query buffer. Trying to recover.\n");
2329
	DRM_ERROR("Can't unpin query buffer. Trying to recover.\n");
1610
 
2330
 
1611
	(void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ);
2331
	(void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ);
1612
	vmw_bo_pin(dev_priv->pinned_bo, false);
2332
	vmw_bo_pin(dev_priv->pinned_bo, false);
1613
	vmw_bo_pin(dev_priv->dummy_query_bo, false);
2333
	vmw_bo_pin(dev_priv->dummy_query_bo, false);
1614
	dev_priv->dummy_query_bo_pinned = false;
2334
	dev_priv->dummy_query_bo_pinned = false;
1615
}
2335
}
1616
 
2336
 
1617
 
2337
 
1618
/**
2338
/**
1619
 * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
2339
 * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
1620
 * query bo.
2340
 * query bo.
1621
 *
2341
 *
1622
 * @dev_priv: The device private structure.
2342
 * @dev_priv: The device private structure.
1623
 * @fence: If non-NULL should point to a struct vmw_fence_obj issued
2343
 * @fence: If non-NULL should point to a struct vmw_fence_obj issued
1624
 * _after_ a query barrier that flushes all queries touching the current
2344
 * _after_ a query barrier that flushes all queries touching the current
1625
 * buffer pointed to by @dev_priv->pinned_bo
2345
 * buffer pointed to by @dev_priv->pinned_bo
1626
 *
2346
 *
1627
 * This function should be used to unpin the pinned query bo, or
2347
 * This function should be used to unpin the pinned query bo, or
1628
 * as a query barrier when we need to make sure that all queries have
2348
 * as a query barrier when we need to make sure that all queries have
1629
 * finished before the next fifo command. (For example on hardware
2349
 * finished before the next fifo command. (For example on hardware
1630
 * context destructions where the hardware may otherwise leak unfinished
2350
 * context destructions where the hardware may otherwise leak unfinished
1631
 * queries).
2351
 * queries).
1632
 *
2352
 *
1633
 * This function does not return any failure codes, but make attempts
2353
 * This function does not return any failure codes, but make attempts
1634
 * to do safe unpinning in case of errors.
2354
 * to do safe unpinning in case of errors.
1635
 *
2355
 *
1636
 * The function will synchronize on the previous query barrier, and will
2356
 * The function will synchronize on the previous query barrier, and will
1637
 * thus not finish until that barrier has executed.
2357
 * thus not finish until that barrier has executed.
1638
 *
2358
 *
1639
 * the @dev_priv->cmdbuf_mutex needs to be held by the current thread
2359
 * the @dev_priv->cmdbuf_mutex needs to be held by the current thread
1640
 * before calling this function.
2360
 * before calling this function.
1641
 */
2361
 */
1642
void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
2362
void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
1643
				     struct vmw_fence_obj *fence)
2363
				     struct vmw_fence_obj *fence)
1644
{
2364
{
1645
	int ret = 0;
2365
	int ret = 0;
1646
	struct list_head validate_list;
2366
	struct list_head validate_list;
1647
	struct ttm_validate_buffer pinned_val, query_val;
2367
	struct ttm_validate_buffer pinned_val, query_val;
1648
	struct vmw_fence_obj *lfence = NULL;
2368
	struct vmw_fence_obj *lfence = NULL;
1649
	struct ww_acquire_ctx ticket;
2369
	struct ww_acquire_ctx ticket;
1650
 
2370
 
1651
	if (dev_priv->pinned_bo == NULL)
2371
	if (dev_priv->pinned_bo == NULL)
1652
		goto out_unlock;
2372
		goto out_unlock;
1653
 
2373
 
1654
	INIT_LIST_HEAD(&validate_list);
2374
	INIT_LIST_HEAD(&validate_list);
1655
 
2375
 
1656
	pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo);
2376
	pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo);
1657
	list_add_tail(&pinned_val.head, &validate_list);
2377
	list_add_tail(&pinned_val.head, &validate_list);
1658
 
2378
 
1659
	query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo);
2379
	query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo);
1660
	list_add_tail(&query_val.head, &validate_list);
2380
	list_add_tail(&query_val.head, &validate_list);
1661
 
2381
 
1662
	do {
2382
	do {
1663
		ret = ttm_eu_reserve_buffers(&ticket, &validate_list);
2383
		ret = ttm_eu_reserve_buffers(&ticket, &validate_list);
1664
	} while (ret == -ERESTARTSYS);
2384
	} while (ret == -ERESTARTSYS);
1665
 
2385
 
1666
	if (unlikely(ret != 0)) {
2386
	if (unlikely(ret != 0)) {
1667
		vmw_execbuf_unpin_panic(dev_priv);
2387
		vmw_execbuf_unpin_panic(dev_priv);
1668
		goto out_no_reserve;
2388
		goto out_no_reserve;
1669
	}
2389
	}
1670
 
2390
 
1671
	if (dev_priv->query_cid_valid) {
2391
	if (dev_priv->query_cid_valid) {
1672
		BUG_ON(fence != NULL);
2392
		BUG_ON(fence != NULL);
1673
		ret = vmw_fifo_emit_dummy_query(dev_priv, dev_priv->query_cid);
2393
		ret = vmw_fifo_emit_dummy_query(dev_priv, dev_priv->query_cid);
1674
		if (unlikely(ret != 0)) {
2394
		if (unlikely(ret != 0)) {
1675
			vmw_execbuf_unpin_panic(dev_priv);
2395
			vmw_execbuf_unpin_panic(dev_priv);
1676
			goto out_no_emit;
2396
			goto out_no_emit;
1677
		}
2397
		}
1678
		dev_priv->query_cid_valid = false;
2398
		dev_priv->query_cid_valid = false;
1679
	}
2399
	}
1680
 
2400
 
1681
	vmw_bo_pin(dev_priv->pinned_bo, false);
2401
	vmw_bo_pin(dev_priv->pinned_bo, false);
1682
	vmw_bo_pin(dev_priv->dummy_query_bo, false);
2402
	vmw_bo_pin(dev_priv->dummy_query_bo, false);
1683
	dev_priv->dummy_query_bo_pinned = false;
2403
	dev_priv->dummy_query_bo_pinned = false;
1684
 
2404
 
1685
	if (fence == NULL) {
2405
	if (fence == NULL) {
1686
		(void) vmw_execbuf_fence_commands(NULL, dev_priv, &lfence,
2406
		(void) vmw_execbuf_fence_commands(NULL, dev_priv, &lfence,
1687
						  NULL);
2407
						  NULL);
1688
		fence = lfence;
2408
		fence = lfence;
1689
	}
2409
	}
1690
	ttm_eu_fence_buffer_objects(&ticket, &validate_list, (void *) fence);
2410
	ttm_eu_fence_buffer_objects(&ticket, &validate_list, (void *) fence);
1691
	if (lfence != NULL)
2411
	if (lfence != NULL)
1692
		vmw_fence_obj_unreference(&lfence);
2412
		vmw_fence_obj_unreference(&lfence);
1693
 
2413
 
1694
	ttm_bo_unref(&query_val.bo);
2414
	ttm_bo_unref(&query_val.bo);
1695
	ttm_bo_unref(&pinned_val.bo);
2415
	ttm_bo_unref(&pinned_val.bo);
1696
	ttm_bo_unref(&dev_priv->pinned_bo);
2416
	ttm_bo_unref(&dev_priv->pinned_bo);
1697
 
2417
 
1698
out_unlock:
2418
out_unlock:
1699
	return;
2419
	return;
1700
 
2420
 
1701
out_no_emit:
2421
out_no_emit:
1702
	ttm_eu_backoff_reservation(&ticket, &validate_list);
2422
	ttm_eu_backoff_reservation(&ticket, &validate_list);
1703
out_no_reserve:
2423
out_no_reserve:
1704
	ttm_bo_unref(&query_val.bo);
2424
	ttm_bo_unref(&query_val.bo);
1705
	ttm_bo_unref(&pinned_val.bo);
2425
	ttm_bo_unref(&pinned_val.bo);
1706
	ttm_bo_unref(&dev_priv->pinned_bo);
2426
	ttm_bo_unref(&dev_priv->pinned_bo);
1707
}
2427
}
1708
 
2428
 
1709
/**
2429
/**
1710
 * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
2430
 * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
1711
 * query bo.
2431
 * query bo.
1712
 *
2432
 *
1713
 * @dev_priv: The device private structure.
2433
 * @dev_priv: The device private structure.
1714
 *
2434
 *
1715
 * This function should be used to unpin the pinned query bo, or
2435
 * This function should be used to unpin the pinned query bo, or
1716
 * as a query barrier when we need to make sure that all queries have
2436
 * as a query barrier when we need to make sure that all queries have
1717
 * finished before the next fifo command. (For example on hardware
2437
 * finished before the next fifo command. (For example on hardware
1718
 * context destructions where the hardware may otherwise leak unfinished
2438
 * context destructions where the hardware may otherwise leak unfinished
1719
 * queries).
2439
 * queries).
1720
 *
2440
 *
1721
 * This function does not return any failure codes, but make attempts
2441
 * This function does not return any failure codes, but make attempts
1722
 * to do safe unpinning in case of errors.
2442
 * to do safe unpinning in case of errors.
1723
 *
2443
 *
1724
 * The function will synchronize on the previous query barrier, and will
2444
 * The function will synchronize on the previous query barrier, and will
1725
 * thus not finish until that barrier has executed.
2445
 * thus not finish until that barrier has executed.
1726
 */
2446
 */
1727
void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv)
2447
void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv)
1728
{
2448
{
1729
	mutex_lock(&dev_priv->cmdbuf_mutex);
2449
	mutex_lock(&dev_priv->cmdbuf_mutex);
1730
	if (dev_priv->query_cid_valid)
2450
	if (dev_priv->query_cid_valid)
1731
		__vmw_execbuf_release_pinned_bo(dev_priv, NULL);
2451
		__vmw_execbuf_release_pinned_bo(dev_priv, NULL);
1732
	mutex_unlock(&dev_priv->cmdbuf_mutex);
2452
	mutex_unlock(&dev_priv->cmdbuf_mutex);
1733
}
2453
}
1734
 
2454
 
1735
 
2455
 
1736
int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
2456
int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
1737
		      struct drm_file *file_priv)
2457
		      struct drm_file *file_priv)
1738
{
2458
{
1739
	struct vmw_private *dev_priv = vmw_priv(dev);
2459
	struct vmw_private *dev_priv = vmw_priv(dev);
1740
	struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data;
2460
	struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data;
1741
//   struct vmw_master *vmaster = vmw_master(file_priv->master);
2461
//   struct vmw_master *vmaster = vmw_master(file_priv->master);
1742
	int ret;
2462
	int ret;
1743
 
2463
 
1744
	/*
2464
	/*
1745
	 * This will allow us to extend the ioctl argument while
2465
	 * This will allow us to extend the ioctl argument while
1746
	 * maintaining backwards compatibility:
2466
	 * maintaining backwards compatibility:
1747
	 * We take different code paths depending on the value of
2467
	 * We take different code paths depending on the value of
1748
	 * arg->version.
2468
	 * arg->version.
1749
	 */
2469
	 */
1750
 
2470
 
1751
	if (unlikely(arg->version != DRM_VMW_EXECBUF_VERSION)) {
2471
	if (unlikely(arg->version != DRM_VMW_EXECBUF_VERSION)) {
1752
		DRM_ERROR("Incorrect execbuf version.\n");
2472
		DRM_ERROR("Incorrect execbuf version.\n");
1753
		DRM_ERROR("You're running outdated experimental "
2473
		DRM_ERROR("You're running outdated experimental "
1754
			  "vmwgfx user-space drivers.");
2474
			  "vmwgfx user-space drivers.");
1755
		return -EINVAL;
2475
		return -EINVAL;
1756
	}
2476
	}
1757
 
2477
 
1758
//   ret = ttm_read_lock(&vmaster->lock, true);
2478
//   ret = ttm_read_lock(&vmaster->lock, true);
1759
	if (unlikely(ret != 0))
2479
	if (unlikely(ret != 0))
1760
		return ret;
2480
		return ret;
1761
 
2481
 
1762
	ret = vmw_execbuf_process(file_priv, dev_priv,
2482
	ret = vmw_execbuf_process(file_priv, dev_priv,
1763
				  (void __user *)(unsigned long)arg->commands,
2483
				  (void __user *)(unsigned long)arg->commands,
1764
				  NULL, arg->command_size, arg->throttle_us,
2484
				  NULL, arg->command_size, arg->throttle_us,
1765
				  (void __user *)(unsigned long)arg->fence_rep,
2485
				  (void __user *)(unsigned long)arg->fence_rep,
1766
				  NULL);
2486
				  NULL);
1767
 
2487
 
1768
	if (unlikely(ret != 0))
2488
	if (unlikely(ret != 0))
1769
		goto out_unlock;
2489
		goto out_unlock;
1770
 
2490
 
1771
//   vmw_kms_cursor_post_execbuf(dev_priv);
2491
//   vmw_kms_cursor_post_execbuf(dev_priv);
1772
 
2492
 
1773
out_unlock:
2493
out_unlock:
1774
//   ttm_read_unlock(&vmaster->lock);
2494
//   ttm_read_unlock(&vmaster->lock);
1775
	return ret;
2495
	return ret;
1776
}
2496
}