xref: /linux/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c (revision b9b77222d4ff6b5bb8f5d87fca20de0910618bb9)
1 /**************************************************************************
2  *
3  * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
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
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
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,
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,
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
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include <drm/ttm/ttm_placement.h>
29 
30 #include "vmwgfx_drv.h"
31 #include "vmwgfx_resource_priv.h"
32 #include "vmwgfx_so.h"
33 #include "vmwgfx_binding.h"
34 #include "device_include/svga3d_surfacedefs.h"
35 
36 
37 /**
38  * struct vmw_user_surface - User-space visible surface resource
39  *
40  * @base:           The TTM base object handling user-space visibility.
41  * @srf:            The surface metadata.
42  * @size:           TTM accounting size for the surface.
43  * @master: master of the creating client. Used for security check.
44  */
45 struct vmw_user_surface {
46 	struct ttm_prime_object prime;
47 	struct vmw_surface srf;
48 	uint32_t size;
49 	struct drm_master *master;
50 	struct ttm_base_object *backup_base;
51 };
52 
53 /**
54  * struct vmw_surface_offset - Backing store mip level offset info
55  *
56  * @face:           Surface face.
57  * @mip:            Mip level.
58  * @bo_offset:      Offset into backing store of this mip level.
59  *
60  */
61 struct vmw_surface_offset {
62 	uint32_t face;
63 	uint32_t mip;
64 	uint32_t bo_offset;
65 };
66 
67 static void vmw_user_surface_free(struct vmw_resource *res);
68 static struct vmw_resource *
69 vmw_user_surface_base_to_res(struct ttm_base_object *base);
70 static int vmw_legacy_srf_bind(struct vmw_resource *res,
71 			       struct ttm_validate_buffer *val_buf);
72 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
73 				 bool readback,
74 				 struct ttm_validate_buffer *val_buf);
75 static int vmw_legacy_srf_create(struct vmw_resource *res);
76 static int vmw_legacy_srf_destroy(struct vmw_resource *res);
77 static int vmw_gb_surface_create(struct vmw_resource *res);
78 static int vmw_gb_surface_bind(struct vmw_resource *res,
79 			       struct ttm_validate_buffer *val_buf);
80 static int vmw_gb_surface_unbind(struct vmw_resource *res,
81 				 bool readback,
82 				 struct ttm_validate_buffer *val_buf);
83 static int vmw_gb_surface_destroy(struct vmw_resource *res);
84 
85 
86 static const struct vmw_user_resource_conv user_surface_conv = {
87 	.object_type = VMW_RES_SURFACE,
88 	.base_obj_to_res = vmw_user_surface_base_to_res,
89 	.res_free = vmw_user_surface_free
90 };
91 
92 const struct vmw_user_resource_conv *user_surface_converter =
93 	&user_surface_conv;
94 
95 
96 static uint64_t vmw_user_surface_size;
97 
98 static const struct vmw_res_func vmw_legacy_surface_func = {
99 	.res_type = vmw_res_surface,
100 	.needs_backup = false,
101 	.may_evict = true,
102 	.type_name = "legacy surfaces",
103 	.backup_placement = &vmw_srf_placement,
104 	.create = &vmw_legacy_srf_create,
105 	.destroy = &vmw_legacy_srf_destroy,
106 	.bind = &vmw_legacy_srf_bind,
107 	.unbind = &vmw_legacy_srf_unbind
108 };
109 
110 static const struct vmw_res_func vmw_gb_surface_func = {
111 	.res_type = vmw_res_surface,
112 	.needs_backup = true,
113 	.may_evict = true,
114 	.type_name = "guest backed surfaces",
115 	.backup_placement = &vmw_mob_placement,
116 	.create = vmw_gb_surface_create,
117 	.destroy = vmw_gb_surface_destroy,
118 	.bind = vmw_gb_surface_bind,
119 	.unbind = vmw_gb_surface_unbind
120 };
121 
122 /**
123  * struct vmw_surface_dma - SVGA3D DMA command
124  */
125 struct vmw_surface_dma {
126 	SVGA3dCmdHeader header;
127 	SVGA3dCmdSurfaceDMA body;
128 	SVGA3dCopyBox cb;
129 	SVGA3dCmdSurfaceDMASuffix suffix;
130 };
131 
132 /**
133  * struct vmw_surface_define - SVGA3D Surface Define command
134  */
135 struct vmw_surface_define {
136 	SVGA3dCmdHeader header;
137 	SVGA3dCmdDefineSurface body;
138 };
139 
140 /**
141  * struct vmw_surface_destroy - SVGA3D Surface Destroy command
142  */
143 struct vmw_surface_destroy {
144 	SVGA3dCmdHeader header;
145 	SVGA3dCmdDestroySurface body;
146 };
147 
148 
149 /**
150  * vmw_surface_dma_size - Compute fifo size for a dma command.
151  *
152  * @srf: Pointer to a struct vmw_surface
153  *
154  * Computes the required size for a surface dma command for backup or
155  * restoration of the surface represented by @srf.
156  */
157 static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf)
158 {
159 	return srf->num_sizes * sizeof(struct vmw_surface_dma);
160 }
161 
162 
163 /**
164  * vmw_surface_define_size - Compute fifo size for a surface define command.
165  *
166  * @srf: Pointer to a struct vmw_surface
167  *
168  * Computes the required size for a surface define command for the definition
169  * of the surface represented by @srf.
170  */
171 static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf)
172 {
173 	return sizeof(struct vmw_surface_define) + srf->num_sizes *
174 		sizeof(SVGA3dSize);
175 }
176 
177 
178 /**
179  * vmw_surface_destroy_size - Compute fifo size for a surface destroy command.
180  *
181  * Computes the required size for a surface destroy command for the destruction
182  * of a hw surface.
183  */
184 static inline uint32_t vmw_surface_destroy_size(void)
185 {
186 	return sizeof(struct vmw_surface_destroy);
187 }
188 
189 /**
190  * vmw_surface_destroy_encode - Encode a surface_destroy command.
191  *
192  * @id: The surface id
193  * @cmd_space: Pointer to memory area in which the commands should be encoded.
194  */
195 static void vmw_surface_destroy_encode(uint32_t id,
196 				       void *cmd_space)
197 {
198 	struct vmw_surface_destroy *cmd = (struct vmw_surface_destroy *)
199 		cmd_space;
200 
201 	cmd->header.id = SVGA_3D_CMD_SURFACE_DESTROY;
202 	cmd->header.size = sizeof(cmd->body);
203 	cmd->body.sid = id;
204 }
205 
206 /**
207  * vmw_surface_define_encode - Encode a surface_define command.
208  *
209  * @srf: Pointer to a struct vmw_surface object.
210  * @cmd_space: Pointer to memory area in which the commands should be encoded.
211  */
212 static void vmw_surface_define_encode(const struct vmw_surface *srf,
213 				      void *cmd_space)
214 {
215 	struct vmw_surface_define *cmd = (struct vmw_surface_define *)
216 		cmd_space;
217 	struct drm_vmw_size *src_size;
218 	SVGA3dSize *cmd_size;
219 	uint32_t cmd_len;
220 	int i;
221 
222 	cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize);
223 
224 	cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE;
225 	cmd->header.size = cmd_len;
226 	cmd->body.sid = srf->res.id;
227 	cmd->body.surfaceFlags = srf->flags;
228 	cmd->body.format = srf->format;
229 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
230 		cmd->body.face[i].numMipLevels = srf->mip_levels[i];
231 
232 	cmd += 1;
233 	cmd_size = (SVGA3dSize *) cmd;
234 	src_size = srf->sizes;
235 
236 	for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) {
237 		cmd_size->width = src_size->width;
238 		cmd_size->height = src_size->height;
239 		cmd_size->depth = src_size->depth;
240 	}
241 }
242 
243 /**
244  * vmw_surface_dma_encode - Encode a surface_dma command.
245  *
246  * @srf: Pointer to a struct vmw_surface object.
247  * @cmd_space: Pointer to memory area in which the commands should be encoded.
248  * @ptr: Pointer to an SVGAGuestPtr indicating where the surface contents
249  * should be placed or read from.
250  * @to_surface: Boolean whether to DMA to the surface or from the surface.
251  */
252 static void vmw_surface_dma_encode(struct vmw_surface *srf,
253 				   void *cmd_space,
254 				   const SVGAGuestPtr *ptr,
255 				   bool to_surface)
256 {
257 	uint32_t i;
258 	struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space;
259 	const struct svga3d_surface_desc *desc =
260 		svga3dsurface_get_desc(srf->format);
261 
262 	for (i = 0; i < srf->num_sizes; ++i) {
263 		SVGA3dCmdHeader *header = &cmd->header;
264 		SVGA3dCmdSurfaceDMA *body = &cmd->body;
265 		SVGA3dCopyBox *cb = &cmd->cb;
266 		SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix;
267 		const struct vmw_surface_offset *cur_offset = &srf->offsets[i];
268 		const struct drm_vmw_size *cur_size = &srf->sizes[i];
269 
270 		header->id = SVGA_3D_CMD_SURFACE_DMA;
271 		header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix);
272 
273 		body->guest.ptr = *ptr;
274 		body->guest.ptr.offset += cur_offset->bo_offset;
275 		body->guest.pitch = svga3dsurface_calculate_pitch(desc,
276 								  cur_size);
277 		body->host.sid = srf->res.id;
278 		body->host.face = cur_offset->face;
279 		body->host.mipmap = cur_offset->mip;
280 		body->transfer = ((to_surface) ?  SVGA3D_WRITE_HOST_VRAM :
281 				  SVGA3D_READ_HOST_VRAM);
282 		cb->x = 0;
283 		cb->y = 0;
284 		cb->z = 0;
285 		cb->srcx = 0;
286 		cb->srcy = 0;
287 		cb->srcz = 0;
288 		cb->w = cur_size->width;
289 		cb->h = cur_size->height;
290 		cb->d = cur_size->depth;
291 
292 		suffix->suffixSize = sizeof(*suffix);
293 		suffix->maximumOffset =
294 			svga3dsurface_get_image_buffer_size(desc, cur_size,
295 							    body->guest.pitch);
296 		suffix->flags.discard = 0;
297 		suffix->flags.unsynchronized = 0;
298 		suffix->flags.reserved = 0;
299 		++cmd;
300 	}
301 };
302 
303 
304 /**
305  * vmw_hw_surface_destroy - destroy a Device surface
306  *
307  * @res:        Pointer to a struct vmw_resource embedded in a struct
308  *              vmw_surface.
309  *
310  * Destroys a the device surface associated with a struct vmw_surface if
311  * any, and adjusts accounting and resource count accordingly.
312  */
313 static void vmw_hw_surface_destroy(struct vmw_resource *res)
314 {
315 
316 	struct vmw_private *dev_priv = res->dev_priv;
317 	struct vmw_surface *srf;
318 	void *cmd;
319 
320 	if (res->func->destroy == vmw_gb_surface_destroy) {
321 		(void) vmw_gb_surface_destroy(res);
322 		return;
323 	}
324 
325 	if (res->id != -1) {
326 
327 		cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size());
328 		if (unlikely(!cmd)) {
329 			DRM_ERROR("Failed reserving FIFO space for surface "
330 				  "destruction.\n");
331 			return;
332 		}
333 
334 		vmw_surface_destroy_encode(res->id, cmd);
335 		vmw_fifo_commit(dev_priv, vmw_surface_destroy_size());
336 
337 		/*
338 		 * used_memory_size_atomic, or separate lock
339 		 * to avoid taking dev_priv::cmdbuf_mutex in
340 		 * the destroy path.
341 		 */
342 
343 		mutex_lock(&dev_priv->cmdbuf_mutex);
344 		srf = vmw_res_to_srf(res);
345 		dev_priv->used_memory_size -= res->backup_size;
346 		mutex_unlock(&dev_priv->cmdbuf_mutex);
347 	}
348 }
349 
350 /**
351  * vmw_legacy_srf_create - Create a device surface as part of the
352  * resource validation process.
353  *
354  * @res: Pointer to a struct vmw_surface.
355  *
356  * If the surface doesn't have a hw id.
357  *
358  * Returns -EBUSY if there wasn't sufficient device resources to
359  * complete the validation. Retry after freeing up resources.
360  *
361  * May return other errors if the kernel is out of guest resources.
362  */
363 static int vmw_legacy_srf_create(struct vmw_resource *res)
364 {
365 	struct vmw_private *dev_priv = res->dev_priv;
366 	struct vmw_surface *srf;
367 	uint32_t submit_size;
368 	uint8_t *cmd;
369 	int ret;
370 
371 	if (likely(res->id != -1))
372 		return 0;
373 
374 	srf = vmw_res_to_srf(res);
375 	if (unlikely(dev_priv->used_memory_size + res->backup_size >=
376 		     dev_priv->memory_size))
377 		return -EBUSY;
378 
379 	/*
380 	 * Alloc id for the resource.
381 	 */
382 
383 	ret = vmw_resource_alloc_id(res);
384 	if (unlikely(ret != 0)) {
385 		DRM_ERROR("Failed to allocate a surface id.\n");
386 		goto out_no_id;
387 	}
388 
389 	if (unlikely(res->id >= SVGA3D_MAX_SURFACE_IDS)) {
390 		ret = -EBUSY;
391 		goto out_no_fifo;
392 	}
393 
394 	/*
395 	 * Encode surface define- commands.
396 	 */
397 
398 	submit_size = vmw_surface_define_size(srf);
399 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
400 	if (unlikely(!cmd)) {
401 		DRM_ERROR("Failed reserving FIFO space for surface "
402 			  "creation.\n");
403 		ret = -ENOMEM;
404 		goto out_no_fifo;
405 	}
406 
407 	vmw_surface_define_encode(srf, cmd);
408 	vmw_fifo_commit(dev_priv, submit_size);
409 	vmw_fifo_resource_inc(dev_priv);
410 
411 	/*
412 	 * Surface memory usage accounting.
413 	 */
414 
415 	dev_priv->used_memory_size += res->backup_size;
416 	return 0;
417 
418 out_no_fifo:
419 	vmw_resource_release_id(res);
420 out_no_id:
421 	return ret;
422 }
423 
424 /**
425  * vmw_legacy_srf_dma - Copy backup data to or from a legacy surface.
426  *
427  * @res:            Pointer to a struct vmw_res embedded in a struct
428  *                  vmw_surface.
429  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
430  *                  information about the backup buffer.
431  * @bind:           Boolean wether to DMA to the surface.
432  *
433  * Transfer backup data to or from a legacy surface as part of the
434  * validation process.
435  * May return other errors if the kernel is out of guest resources.
436  * The backup buffer will be fenced or idle upon successful completion,
437  * and if the surface needs persistent backup storage, the backup buffer
438  * will also be returned reserved iff @bind is true.
439  */
440 static int vmw_legacy_srf_dma(struct vmw_resource *res,
441 			      struct ttm_validate_buffer *val_buf,
442 			      bool bind)
443 {
444 	SVGAGuestPtr ptr;
445 	struct vmw_fence_obj *fence;
446 	uint32_t submit_size;
447 	struct vmw_surface *srf = vmw_res_to_srf(res);
448 	uint8_t *cmd;
449 	struct vmw_private *dev_priv = res->dev_priv;
450 
451 	BUG_ON(!val_buf->bo);
452 	submit_size = vmw_surface_dma_size(srf);
453 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
454 	if (unlikely(!cmd)) {
455 		DRM_ERROR("Failed reserving FIFO space for surface "
456 			  "DMA.\n");
457 		return -ENOMEM;
458 	}
459 	vmw_bo_get_guest_ptr(val_buf->bo, &ptr);
460 	vmw_surface_dma_encode(srf, cmd, &ptr, bind);
461 
462 	vmw_fifo_commit(dev_priv, submit_size);
463 
464 	/*
465 	 * Create a fence object and fence the backup buffer.
466 	 */
467 
468 	(void) vmw_execbuf_fence_commands(NULL, dev_priv,
469 					  &fence, NULL);
470 
471 	vmw_fence_single_bo(val_buf->bo, fence);
472 
473 	if (likely(fence != NULL))
474 		vmw_fence_obj_unreference(&fence);
475 
476 	return 0;
477 }
478 
479 /**
480  * vmw_legacy_srf_bind - Perform a legacy surface bind as part of the
481  *                       surface validation process.
482  *
483  * @res:            Pointer to a struct vmw_res embedded in a struct
484  *                  vmw_surface.
485  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
486  *                  information about the backup buffer.
487  *
488  * This function will copy backup data to the surface if the
489  * backup buffer is dirty.
490  */
491 static int vmw_legacy_srf_bind(struct vmw_resource *res,
492 			       struct ttm_validate_buffer *val_buf)
493 {
494 	if (!res->backup_dirty)
495 		return 0;
496 
497 	return vmw_legacy_srf_dma(res, val_buf, true);
498 }
499 
500 
501 /**
502  * vmw_legacy_srf_unbind - Perform a legacy surface unbind as part of the
503  *                         surface eviction process.
504  *
505  * @res:            Pointer to a struct vmw_res embedded in a struct
506  *                  vmw_surface.
507  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
508  *                  information about the backup buffer.
509  *
510  * This function will copy backup data from the surface.
511  */
512 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
513 				 bool readback,
514 				 struct ttm_validate_buffer *val_buf)
515 {
516 	if (unlikely(readback))
517 		return vmw_legacy_srf_dma(res, val_buf, false);
518 	return 0;
519 }
520 
521 /**
522  * vmw_legacy_srf_destroy - Destroy a device surface as part of a
523  *                          resource eviction process.
524  *
525  * @res:            Pointer to a struct vmw_res embedded in a struct
526  *                  vmw_surface.
527  */
528 static int vmw_legacy_srf_destroy(struct vmw_resource *res)
529 {
530 	struct vmw_private *dev_priv = res->dev_priv;
531 	uint32_t submit_size;
532 	uint8_t *cmd;
533 
534 	BUG_ON(res->id == -1);
535 
536 	/*
537 	 * Encode the dma- and surface destroy commands.
538 	 */
539 
540 	submit_size = vmw_surface_destroy_size();
541 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
542 	if (unlikely(!cmd)) {
543 		DRM_ERROR("Failed reserving FIFO space for surface "
544 			  "eviction.\n");
545 		return -ENOMEM;
546 	}
547 
548 	vmw_surface_destroy_encode(res->id, cmd);
549 	vmw_fifo_commit(dev_priv, submit_size);
550 
551 	/*
552 	 * Surface memory usage accounting.
553 	 */
554 
555 	dev_priv->used_memory_size -= res->backup_size;
556 
557 	/*
558 	 * Release the surface ID.
559 	 */
560 
561 	vmw_resource_release_id(res);
562 	vmw_fifo_resource_dec(dev_priv);
563 
564 	return 0;
565 }
566 
567 
568 /**
569  * vmw_surface_init - initialize a struct vmw_surface
570  *
571  * @dev_priv:       Pointer to a device private struct.
572  * @srf:            Pointer to the struct vmw_surface to initialize.
573  * @res_free:       Pointer to a resource destructor used to free
574  *                  the object.
575  */
576 static int vmw_surface_init(struct vmw_private *dev_priv,
577 			    struct vmw_surface *srf,
578 			    void (*res_free) (struct vmw_resource *res))
579 {
580 	int ret;
581 	struct vmw_resource *res = &srf->res;
582 
583 	BUG_ON(!res_free);
584 	ret = vmw_resource_init(dev_priv, res, true, res_free,
585 				(dev_priv->has_mob) ? &vmw_gb_surface_func :
586 				&vmw_legacy_surface_func);
587 
588 	if (unlikely(ret != 0)) {
589 		res_free(res);
590 		return ret;
591 	}
592 
593 	/*
594 	 * The surface won't be visible to hardware until a
595 	 * surface validate.
596 	 */
597 
598 	INIT_LIST_HEAD(&srf->view_list);
599 	vmw_resource_activate(res, vmw_hw_surface_destroy);
600 	return ret;
601 }
602 
603 /**
604  * vmw_user_surface_base_to_res - TTM base object to resource converter for
605  *                                user visible surfaces
606  *
607  * @base:           Pointer to a TTM base object
608  *
609  * Returns the struct vmw_resource embedded in a struct vmw_surface
610  * for the user-visible object identified by the TTM base object @base.
611  */
612 static struct vmw_resource *
613 vmw_user_surface_base_to_res(struct ttm_base_object *base)
614 {
615 	return &(container_of(base, struct vmw_user_surface,
616 			      prime.base)->srf.res);
617 }
618 
619 /**
620  * vmw_user_surface_free - User visible surface resource destructor
621  *
622  * @res:            A struct vmw_resource embedded in a struct vmw_surface.
623  */
624 static void vmw_user_surface_free(struct vmw_resource *res)
625 {
626 	struct vmw_surface *srf = vmw_res_to_srf(res);
627 	struct vmw_user_surface *user_srf =
628 	    container_of(srf, struct vmw_user_surface, srf);
629 	struct vmw_private *dev_priv = srf->res.dev_priv;
630 	uint32_t size = user_srf->size;
631 
632 	if (user_srf->master)
633 		drm_master_put(&user_srf->master);
634 	kfree(srf->offsets);
635 	kfree(srf->sizes);
636 	kfree(srf->snooper.image);
637 	ttm_prime_object_kfree(user_srf, prime);
638 	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
639 }
640 
641 /**
642  * vmw_user_surface_free - User visible surface TTM base object destructor
643  *
644  * @p_base:         Pointer to a pointer to a TTM base object
645  *                  embedded in a struct vmw_user_surface.
646  *
647  * Drops the base object's reference on its resource, and the
648  * pointer pointed to by *p_base is set to NULL.
649  */
650 static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
651 {
652 	struct ttm_base_object *base = *p_base;
653 	struct vmw_user_surface *user_srf =
654 	    container_of(base, struct vmw_user_surface, prime.base);
655 	struct vmw_resource *res = &user_srf->srf.res;
656 
657 	*p_base = NULL;
658 	if (user_srf->backup_base)
659 		ttm_base_object_unref(&user_srf->backup_base);
660 	vmw_resource_unreference(&res);
661 }
662 
663 /**
664  * vmw_user_surface_destroy_ioctl - Ioctl function implementing
665  *                                  the user surface destroy functionality.
666  *
667  * @dev:            Pointer to a struct drm_device.
668  * @data:           Pointer to data copied from / to user-space.
669  * @file_priv:      Pointer to a drm file private structure.
670  */
671 int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
672 			      struct drm_file *file_priv)
673 {
674 	struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
675 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
676 
677 	return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE);
678 }
679 
680 /**
681  * vmw_user_surface_define_ioctl - Ioctl function implementing
682  *                                  the user surface define functionality.
683  *
684  * @dev:            Pointer to a struct drm_device.
685  * @data:           Pointer to data copied from / to user-space.
686  * @file_priv:      Pointer to a drm file private structure.
687  */
688 int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
689 			     struct drm_file *file_priv)
690 {
691 	struct vmw_private *dev_priv = vmw_priv(dev);
692 	struct vmw_user_surface *user_srf;
693 	struct vmw_surface *srf;
694 	struct vmw_resource *res;
695 	struct vmw_resource *tmp;
696 	union drm_vmw_surface_create_arg *arg =
697 	    (union drm_vmw_surface_create_arg *)data;
698 	struct drm_vmw_surface_create_req *req = &arg->req;
699 	struct drm_vmw_surface_arg *rep = &arg->rep;
700 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
701 	struct ttm_operation_ctx ctx = {
702 		.interruptible = true,
703 		.no_wait_gpu = false
704 	};
705 	int ret;
706 	int i, j;
707 	uint32_t cur_bo_offset;
708 	struct drm_vmw_size *cur_size;
709 	struct vmw_surface_offset *cur_offset;
710 	uint32_t num_sizes;
711 	uint32_t size;
712 	const struct svga3d_surface_desc *desc;
713 
714 	if (unlikely(vmw_user_surface_size == 0))
715 		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
716 			128;
717 
718 	num_sizes = 0;
719 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
720 		if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
721 			return -EINVAL;
722 		num_sizes += req->mip_levels[i];
723 	}
724 
725 	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
726 	    num_sizes == 0)
727 		return -EINVAL;
728 
729 	size = vmw_user_surface_size + 128 +
730 		ttm_round_pot(num_sizes * sizeof(struct drm_vmw_size)) +
731 		ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset));
732 
733 
734 	desc = svga3dsurface_get_desc(req->format);
735 	if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
736 		DRM_ERROR("Invalid surface format for surface creation.\n");
737 		DRM_ERROR("Format requested is: %d\n", req->format);
738 		return -EINVAL;
739 	}
740 
741 	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
742 	if (unlikely(ret != 0))
743 		return ret;
744 
745 	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
746 				   size, &ctx);
747 	if (unlikely(ret != 0)) {
748 		if (ret != -ERESTARTSYS)
749 			DRM_ERROR("Out of graphics memory for surface"
750 				  " creation.\n");
751 		goto out_unlock;
752 	}
753 
754 	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
755 	if (unlikely(!user_srf)) {
756 		ret = -ENOMEM;
757 		goto out_no_user_srf;
758 	}
759 
760 	srf = &user_srf->srf;
761 	res = &srf->res;
762 
763 	srf->flags = req->flags;
764 	srf->format = req->format;
765 	srf->scanout = req->scanout;
766 
767 	memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels));
768 	srf->num_sizes = num_sizes;
769 	user_srf->size = size;
770 	srf->sizes = memdup_user((struct drm_vmw_size __user *)(unsigned long)
771 				 req->size_addr,
772 				 sizeof(*srf->sizes) * srf->num_sizes);
773 	if (IS_ERR(srf->sizes)) {
774 		ret = PTR_ERR(srf->sizes);
775 		goto out_no_sizes;
776 	}
777 	srf->offsets = kmalloc_array(srf->num_sizes,
778 				     sizeof(*srf->offsets),
779 				     GFP_KERNEL);
780 	if (unlikely(!srf->offsets)) {
781 		ret = -ENOMEM;
782 		goto out_no_offsets;
783 	}
784 
785 	srf->base_size = *srf->sizes;
786 	srf->autogen_filter = SVGA3D_TEX_FILTER_NONE;
787 	srf->multisample_count = 0;
788 
789 	cur_bo_offset = 0;
790 	cur_offset = srf->offsets;
791 	cur_size = srf->sizes;
792 
793 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
794 		for (j = 0; j < srf->mip_levels[i]; ++j) {
795 			uint32_t stride = svga3dsurface_calculate_pitch
796 				(desc, cur_size);
797 
798 			cur_offset->face = i;
799 			cur_offset->mip = j;
800 			cur_offset->bo_offset = cur_bo_offset;
801 			cur_bo_offset += svga3dsurface_get_image_buffer_size
802 				(desc, cur_size, stride);
803 			++cur_offset;
804 			++cur_size;
805 		}
806 	}
807 	res->backup_size = cur_bo_offset;
808 	if (srf->scanout &&
809 	    srf->num_sizes == 1 &&
810 	    srf->sizes[0].width == 64 &&
811 	    srf->sizes[0].height == 64 &&
812 	    srf->format == SVGA3D_A8R8G8B8) {
813 
814 		srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL);
815 		if (!srf->snooper.image) {
816 			DRM_ERROR("Failed to allocate cursor_image\n");
817 			ret = -ENOMEM;
818 			goto out_no_copy;
819 		}
820 	} else {
821 		srf->snooper.image = NULL;
822 	}
823 
824 	user_srf->prime.base.shareable = false;
825 	user_srf->prime.base.tfile = NULL;
826 	if (drm_is_primary_client(file_priv))
827 		user_srf->master = drm_master_get(file_priv->master);
828 
829 	/**
830 	 * From this point, the generic resource management functions
831 	 * destroy the object on failure.
832 	 */
833 
834 	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
835 	if (unlikely(ret != 0))
836 		goto out_unlock;
837 
838 	/*
839 	 * A gb-aware client referencing a shared surface will
840 	 * expect a backup buffer to be present.
841 	 */
842 	if (dev_priv->has_mob && req->shareable) {
843 		uint32_t backup_handle;
844 
845 		ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
846 					    res->backup_size,
847 					    true,
848 					    &backup_handle,
849 					    &res->backup,
850 					    &user_srf->backup_base);
851 		if (unlikely(ret != 0)) {
852 			vmw_resource_unreference(&res);
853 			goto out_unlock;
854 		}
855 	}
856 
857 	tmp = vmw_resource_reference(&srf->res);
858 	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
859 				    req->shareable, VMW_RES_SURFACE,
860 				    &vmw_user_surface_base_release, NULL);
861 
862 	if (unlikely(ret != 0)) {
863 		vmw_resource_unreference(&tmp);
864 		vmw_resource_unreference(&res);
865 		goto out_unlock;
866 	}
867 
868 	rep->sid = user_srf->prime.base.hash.key;
869 	vmw_resource_unreference(&res);
870 
871 	ttm_read_unlock(&dev_priv->reservation_sem);
872 	return 0;
873 out_no_copy:
874 	kfree(srf->offsets);
875 out_no_offsets:
876 	kfree(srf->sizes);
877 out_no_sizes:
878 	ttm_prime_object_kfree(user_srf, prime);
879 out_no_user_srf:
880 	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
881 out_unlock:
882 	ttm_read_unlock(&dev_priv->reservation_sem);
883 	return ret;
884 }
885 
886 
887 static int
888 vmw_surface_handle_reference(struct vmw_private *dev_priv,
889 			     struct drm_file *file_priv,
890 			     uint32_t u_handle,
891 			     enum drm_vmw_handle_type handle_type,
892 			     struct ttm_base_object **base_p)
893 {
894 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
895 	struct vmw_user_surface *user_srf;
896 	uint32_t handle;
897 	struct ttm_base_object *base;
898 	int ret;
899 	bool require_exist = false;
900 
901 	if (handle_type == DRM_VMW_HANDLE_PRIME) {
902 		ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
903 		if (unlikely(ret != 0))
904 			return ret;
905 	} else {
906 		if (unlikely(drm_is_render_client(file_priv)))
907 			require_exist = true;
908 
909 		if (READ_ONCE(vmw_fpriv(file_priv)->locked_master)) {
910 			DRM_ERROR("Locked master refused legacy "
911 				  "surface reference.\n");
912 			return -EACCES;
913 		}
914 
915 		handle = u_handle;
916 	}
917 
918 	ret = -EINVAL;
919 	base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle);
920 	if (unlikely(!base)) {
921 		DRM_ERROR("Could not find surface to reference.\n");
922 		goto out_no_lookup;
923 	}
924 
925 	if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) {
926 		DRM_ERROR("Referenced object is not a surface.\n");
927 		goto out_bad_resource;
928 	}
929 
930 	if (handle_type != DRM_VMW_HANDLE_PRIME) {
931 		user_srf = container_of(base, struct vmw_user_surface,
932 					prime.base);
933 
934 		/*
935 		 * Make sure the surface creator has the same
936 		 * authenticating master, or is already registered with us.
937 		 */
938 		if (drm_is_primary_client(file_priv) &&
939 		    user_srf->master != file_priv->master)
940 			require_exist = true;
941 
942 		ret = ttm_ref_object_add(tfile, base, TTM_REF_USAGE, NULL,
943 					 require_exist);
944 		if (unlikely(ret != 0)) {
945 			DRM_ERROR("Could not add a reference to a surface.\n");
946 			goto out_bad_resource;
947 		}
948 	}
949 
950 	*base_p = base;
951 	return 0;
952 
953 out_bad_resource:
954 	ttm_base_object_unref(&base);
955 out_no_lookup:
956 	if (handle_type == DRM_VMW_HANDLE_PRIME)
957 		(void) ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE);
958 
959 	return ret;
960 }
961 
962 /**
963  * vmw_user_surface_define_ioctl - Ioctl function implementing
964  *                                  the user surface reference functionality.
965  *
966  * @dev:            Pointer to a struct drm_device.
967  * @data:           Pointer to data copied from / to user-space.
968  * @file_priv:      Pointer to a drm file private structure.
969  */
970 int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
971 				struct drm_file *file_priv)
972 {
973 	struct vmw_private *dev_priv = vmw_priv(dev);
974 	union drm_vmw_surface_reference_arg *arg =
975 	    (union drm_vmw_surface_reference_arg *)data;
976 	struct drm_vmw_surface_arg *req = &arg->req;
977 	struct drm_vmw_surface_create_req *rep = &arg->rep;
978 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
979 	struct vmw_surface *srf;
980 	struct vmw_user_surface *user_srf;
981 	struct drm_vmw_size __user *user_sizes;
982 	struct ttm_base_object *base;
983 	int ret;
984 
985 	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
986 					   req->handle_type, &base);
987 	if (unlikely(ret != 0))
988 		return ret;
989 
990 	user_srf = container_of(base, struct vmw_user_surface, prime.base);
991 	srf = &user_srf->srf;
992 
993 	rep->flags = srf->flags;
994 	rep->format = srf->format;
995 	memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels));
996 	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
997 	    rep->size_addr;
998 
999 	if (user_sizes)
1000 		ret = copy_to_user(user_sizes, &srf->base_size,
1001 				   sizeof(srf->base_size));
1002 	if (unlikely(ret != 0)) {
1003 		DRM_ERROR("copy_to_user failed %p %u\n",
1004 			  user_sizes, srf->num_sizes);
1005 		ttm_ref_object_base_unref(tfile, base->hash.key, TTM_REF_USAGE);
1006 		ret = -EFAULT;
1007 	}
1008 
1009 	ttm_base_object_unref(&base);
1010 
1011 	return ret;
1012 }
1013 
1014 /**
1015  * vmw_surface_define_encode - Encode a surface_define command.
1016  *
1017  * @srf: Pointer to a struct vmw_surface object.
1018  * @cmd_space: Pointer to memory area in which the commands should be encoded.
1019  */
1020 static int vmw_gb_surface_create(struct vmw_resource *res)
1021 {
1022 	struct vmw_private *dev_priv = res->dev_priv;
1023 	struct vmw_surface *srf = vmw_res_to_srf(res);
1024 	uint32_t cmd_len, cmd_id, submit_len;
1025 	int ret;
1026 	struct {
1027 		SVGA3dCmdHeader header;
1028 		SVGA3dCmdDefineGBSurface body;
1029 	} *cmd;
1030 	struct {
1031 		SVGA3dCmdHeader header;
1032 		SVGA3dCmdDefineGBSurface_v2 body;
1033 	} *cmd2;
1034 
1035 	if (likely(res->id != -1))
1036 		return 0;
1037 
1038 	vmw_fifo_resource_inc(dev_priv);
1039 	ret = vmw_resource_alloc_id(res);
1040 	if (unlikely(ret != 0)) {
1041 		DRM_ERROR("Failed to allocate a surface id.\n");
1042 		goto out_no_id;
1043 	}
1044 
1045 	if (unlikely(res->id >= VMWGFX_NUM_GB_SURFACE)) {
1046 		ret = -EBUSY;
1047 		goto out_no_fifo;
1048 	}
1049 
1050 	if (srf->array_size > 0) {
1051 		/* has_dx checked on creation time. */
1052 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2;
1053 		cmd_len = sizeof(cmd2->body);
1054 		submit_len = sizeof(*cmd2);
1055 	} else {
1056 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE;
1057 		cmd_len = sizeof(cmd->body);
1058 		submit_len = sizeof(*cmd);
1059 	}
1060 
1061 	cmd = vmw_fifo_reserve(dev_priv, submit_len);
1062 	cmd2 = (typeof(cmd2))cmd;
1063 	if (unlikely(!cmd)) {
1064 		DRM_ERROR("Failed reserving FIFO space for surface "
1065 			  "creation.\n");
1066 		ret = -ENOMEM;
1067 		goto out_no_fifo;
1068 	}
1069 
1070 	if (srf->array_size > 0) {
1071 		cmd2->header.id = cmd_id;
1072 		cmd2->header.size = cmd_len;
1073 		cmd2->body.sid = srf->res.id;
1074 		cmd2->body.surfaceFlags = srf->flags;
1075 		cmd2->body.format = cpu_to_le32(srf->format);
1076 		cmd2->body.numMipLevels = srf->mip_levels[0];
1077 		cmd2->body.multisampleCount = srf->multisample_count;
1078 		cmd2->body.autogenFilter = srf->autogen_filter;
1079 		cmd2->body.size.width = srf->base_size.width;
1080 		cmd2->body.size.height = srf->base_size.height;
1081 		cmd2->body.size.depth = srf->base_size.depth;
1082 		cmd2->body.arraySize = srf->array_size;
1083 	} else {
1084 		cmd->header.id = cmd_id;
1085 		cmd->header.size = cmd_len;
1086 		cmd->body.sid = srf->res.id;
1087 		cmd->body.surfaceFlags = srf->flags;
1088 		cmd->body.format = cpu_to_le32(srf->format);
1089 		cmd->body.numMipLevels = srf->mip_levels[0];
1090 		cmd->body.multisampleCount = srf->multisample_count;
1091 		cmd->body.autogenFilter = srf->autogen_filter;
1092 		cmd->body.size.width = srf->base_size.width;
1093 		cmd->body.size.height = srf->base_size.height;
1094 		cmd->body.size.depth = srf->base_size.depth;
1095 	}
1096 
1097 	vmw_fifo_commit(dev_priv, submit_len);
1098 
1099 	return 0;
1100 
1101 out_no_fifo:
1102 	vmw_resource_release_id(res);
1103 out_no_id:
1104 	vmw_fifo_resource_dec(dev_priv);
1105 	return ret;
1106 }
1107 
1108 
1109 static int vmw_gb_surface_bind(struct vmw_resource *res,
1110 			       struct ttm_validate_buffer *val_buf)
1111 {
1112 	struct vmw_private *dev_priv = res->dev_priv;
1113 	struct {
1114 		SVGA3dCmdHeader header;
1115 		SVGA3dCmdBindGBSurface body;
1116 	} *cmd1;
1117 	struct {
1118 		SVGA3dCmdHeader header;
1119 		SVGA3dCmdUpdateGBSurface body;
1120 	} *cmd2;
1121 	uint32_t submit_size;
1122 	struct ttm_buffer_object *bo = val_buf->bo;
1123 
1124 	BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
1125 
1126 	submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0);
1127 
1128 	cmd1 = vmw_fifo_reserve(dev_priv, submit_size);
1129 	if (unlikely(!cmd1)) {
1130 		DRM_ERROR("Failed reserving FIFO space for surface "
1131 			  "binding.\n");
1132 		return -ENOMEM;
1133 	}
1134 
1135 	cmd1->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1136 	cmd1->header.size = sizeof(cmd1->body);
1137 	cmd1->body.sid = res->id;
1138 	cmd1->body.mobid = bo->mem.start;
1139 	if (res->backup_dirty) {
1140 		cmd2 = (void *) &cmd1[1];
1141 		cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_SURFACE;
1142 		cmd2->header.size = sizeof(cmd2->body);
1143 		cmd2->body.sid = res->id;
1144 		res->backup_dirty = false;
1145 	}
1146 	vmw_fifo_commit(dev_priv, submit_size);
1147 
1148 	return 0;
1149 }
1150 
1151 static int vmw_gb_surface_unbind(struct vmw_resource *res,
1152 				 bool readback,
1153 				 struct ttm_validate_buffer *val_buf)
1154 {
1155 	struct vmw_private *dev_priv = res->dev_priv;
1156 	struct ttm_buffer_object *bo = val_buf->bo;
1157 	struct vmw_fence_obj *fence;
1158 
1159 	struct {
1160 		SVGA3dCmdHeader header;
1161 		SVGA3dCmdReadbackGBSurface body;
1162 	} *cmd1;
1163 	struct {
1164 		SVGA3dCmdHeader header;
1165 		SVGA3dCmdInvalidateGBSurface body;
1166 	} *cmd2;
1167 	struct {
1168 		SVGA3dCmdHeader header;
1169 		SVGA3dCmdBindGBSurface body;
1170 	} *cmd3;
1171 	uint32_t submit_size;
1172 	uint8_t *cmd;
1173 
1174 
1175 	BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
1176 
1177 	submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2));
1178 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
1179 	if (unlikely(!cmd)) {
1180 		DRM_ERROR("Failed reserving FIFO space for surface "
1181 			  "unbinding.\n");
1182 		return -ENOMEM;
1183 	}
1184 
1185 	if (readback) {
1186 		cmd1 = (void *) cmd;
1187 		cmd1->header.id = SVGA_3D_CMD_READBACK_GB_SURFACE;
1188 		cmd1->header.size = sizeof(cmd1->body);
1189 		cmd1->body.sid = res->id;
1190 		cmd3 = (void *) &cmd1[1];
1191 	} else {
1192 		cmd2 = (void *) cmd;
1193 		cmd2->header.id = SVGA_3D_CMD_INVALIDATE_GB_SURFACE;
1194 		cmd2->header.size = sizeof(cmd2->body);
1195 		cmd2->body.sid = res->id;
1196 		cmd3 = (void *) &cmd2[1];
1197 	}
1198 
1199 	cmd3->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1200 	cmd3->header.size = sizeof(cmd3->body);
1201 	cmd3->body.sid = res->id;
1202 	cmd3->body.mobid = SVGA3D_INVALID_ID;
1203 
1204 	vmw_fifo_commit(dev_priv, submit_size);
1205 
1206 	/*
1207 	 * Create a fence object and fence the backup buffer.
1208 	 */
1209 
1210 	(void) vmw_execbuf_fence_commands(NULL, dev_priv,
1211 					  &fence, NULL);
1212 
1213 	vmw_fence_single_bo(val_buf->bo, fence);
1214 
1215 	if (likely(fence != NULL))
1216 		vmw_fence_obj_unreference(&fence);
1217 
1218 	return 0;
1219 }
1220 
1221 static int vmw_gb_surface_destroy(struct vmw_resource *res)
1222 {
1223 	struct vmw_private *dev_priv = res->dev_priv;
1224 	struct vmw_surface *srf = vmw_res_to_srf(res);
1225 	struct {
1226 		SVGA3dCmdHeader header;
1227 		SVGA3dCmdDestroyGBSurface body;
1228 	} *cmd;
1229 
1230 	if (likely(res->id == -1))
1231 		return 0;
1232 
1233 	mutex_lock(&dev_priv->binding_mutex);
1234 	vmw_view_surface_list_destroy(dev_priv, &srf->view_list);
1235 	vmw_binding_res_list_scrub(&res->binding_head);
1236 
1237 	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
1238 	if (unlikely(!cmd)) {
1239 		DRM_ERROR("Failed reserving FIFO space for surface "
1240 			  "destruction.\n");
1241 		mutex_unlock(&dev_priv->binding_mutex);
1242 		return -ENOMEM;
1243 	}
1244 
1245 	cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SURFACE;
1246 	cmd->header.size = sizeof(cmd->body);
1247 	cmd->body.sid = res->id;
1248 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
1249 	mutex_unlock(&dev_priv->binding_mutex);
1250 	vmw_resource_release_id(res);
1251 	vmw_fifo_resource_dec(dev_priv);
1252 
1253 	return 0;
1254 }
1255 
1256 
1257 /**
1258  * vmw_gb_surface_define_ioctl - Ioctl function implementing
1259  *                               the user surface define functionality.
1260  *
1261  * @dev:            Pointer to a struct drm_device.
1262  * @data:           Pointer to data copied from / to user-space.
1263  * @file_priv:      Pointer to a drm file private structure.
1264  */
1265 int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
1266 				struct drm_file *file_priv)
1267 {
1268 	struct vmw_private *dev_priv = vmw_priv(dev);
1269 	struct vmw_user_surface *user_srf;
1270 	struct vmw_surface *srf;
1271 	struct vmw_resource *res;
1272 	struct vmw_resource *tmp;
1273 	union drm_vmw_gb_surface_create_arg *arg =
1274 	    (union drm_vmw_gb_surface_create_arg *)data;
1275 	struct drm_vmw_gb_surface_create_req *req = &arg->req;
1276 	struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
1277 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1278 	int ret;
1279 	uint32_t size;
1280 	uint32_t backup_handle = 0;
1281 
1282 	if (req->multisample_count != 0)
1283 		return -EINVAL;
1284 
1285 	if (req->mip_levels > DRM_VMW_MAX_MIP_LEVELS)
1286 		return -EINVAL;
1287 
1288 	if (unlikely(vmw_user_surface_size == 0))
1289 		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
1290 			128;
1291 
1292 	size = vmw_user_surface_size + 128;
1293 
1294 	/* Define a surface based on the parameters. */
1295 	ret = vmw_surface_gb_priv_define(dev,
1296 			size,
1297 			req->svga3d_flags,
1298 			req->format,
1299 			req->drm_surface_flags & drm_vmw_surface_flag_scanout,
1300 			req->mip_levels,
1301 			req->multisample_count,
1302 			req->array_size,
1303 			req->base_size,
1304 			&srf);
1305 	if (unlikely(ret != 0))
1306 		return ret;
1307 
1308 	user_srf = container_of(srf, struct vmw_user_surface, srf);
1309 	if (drm_is_primary_client(file_priv))
1310 		user_srf->master = drm_master_get(file_priv->master);
1311 
1312 	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
1313 	if (unlikely(ret != 0))
1314 		return ret;
1315 
1316 	res = &user_srf->srf.res;
1317 
1318 
1319 	if (req->buffer_handle != SVGA3D_INVALID_ID) {
1320 		ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle,
1321 					     &res->backup,
1322 					     &user_srf->backup_base);
1323 		if (ret == 0) {
1324 			if (res->backup->base.num_pages * PAGE_SIZE <
1325 			    res->backup_size) {
1326 				DRM_ERROR("Surface backup buffer is too small.\n");
1327 				vmw_dmabuf_unreference(&res->backup);
1328 				ret = -EINVAL;
1329 				goto out_unlock;
1330 			} else {
1331 				backup_handle = req->buffer_handle;
1332 			}
1333 		}
1334 	} else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer)
1335 		ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
1336 					    res->backup_size,
1337 					    req->drm_surface_flags &
1338 					    drm_vmw_surface_flag_shareable,
1339 					    &backup_handle,
1340 					    &res->backup,
1341 					    &user_srf->backup_base);
1342 
1343 	if (unlikely(ret != 0)) {
1344 		vmw_resource_unreference(&res);
1345 		goto out_unlock;
1346 	}
1347 
1348 	tmp = vmw_resource_reference(res);
1349 	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
1350 				    req->drm_surface_flags &
1351 				    drm_vmw_surface_flag_shareable,
1352 				    VMW_RES_SURFACE,
1353 				    &vmw_user_surface_base_release, NULL);
1354 
1355 	if (unlikely(ret != 0)) {
1356 		vmw_resource_unreference(&tmp);
1357 		vmw_resource_unreference(&res);
1358 		goto out_unlock;
1359 	}
1360 
1361 	rep->handle      = user_srf->prime.base.hash.key;
1362 	rep->backup_size = res->backup_size;
1363 	if (res->backup) {
1364 		rep->buffer_map_handle =
1365 			drm_vma_node_offset_addr(&res->backup->base.vma_node);
1366 		rep->buffer_size = res->backup->base.num_pages * PAGE_SIZE;
1367 		rep->buffer_handle = backup_handle;
1368 	} else {
1369 		rep->buffer_map_handle = 0;
1370 		rep->buffer_size = 0;
1371 		rep->buffer_handle = SVGA3D_INVALID_ID;
1372 	}
1373 
1374 	vmw_resource_unreference(&res);
1375 
1376 out_unlock:
1377 	ttm_read_unlock(&dev_priv->reservation_sem);
1378 	return ret;
1379 }
1380 
1381 /**
1382  * vmw_gb_surface_reference_ioctl - Ioctl function implementing
1383  *                                  the user surface reference functionality.
1384  *
1385  * @dev:            Pointer to a struct drm_device.
1386  * @data:           Pointer to data copied from / to user-space.
1387  * @file_priv:      Pointer to a drm file private structure.
1388  */
1389 int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
1390 				   struct drm_file *file_priv)
1391 {
1392 	struct vmw_private *dev_priv = vmw_priv(dev);
1393 	union drm_vmw_gb_surface_reference_arg *arg =
1394 	    (union drm_vmw_gb_surface_reference_arg *)data;
1395 	struct drm_vmw_surface_arg *req = &arg->req;
1396 	struct drm_vmw_gb_surface_ref_rep *rep = &arg->rep;
1397 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1398 	struct vmw_surface *srf;
1399 	struct vmw_user_surface *user_srf;
1400 	struct ttm_base_object *base;
1401 	uint32_t backup_handle;
1402 	int ret = -EINVAL;
1403 
1404 	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
1405 					   req->handle_type, &base);
1406 	if (unlikely(ret != 0))
1407 		return ret;
1408 
1409 	user_srf = container_of(base, struct vmw_user_surface, prime.base);
1410 	srf = &user_srf->srf;
1411 	if (!srf->res.backup) {
1412 		DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
1413 		goto out_bad_resource;
1414 	}
1415 
1416 	mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
1417 	ret = vmw_user_dmabuf_reference(tfile, srf->res.backup,
1418 					&backup_handle);
1419 	mutex_unlock(&dev_priv->cmdbuf_mutex);
1420 
1421 	if (unlikely(ret != 0)) {
1422 		DRM_ERROR("Could not add a reference to a GB surface "
1423 			  "backup buffer.\n");
1424 		(void) ttm_ref_object_base_unref(tfile, base->hash.key,
1425 						 TTM_REF_USAGE);
1426 		goto out_bad_resource;
1427 	}
1428 
1429 	rep->creq.svga3d_flags = srf->flags;
1430 	rep->creq.format = srf->format;
1431 	rep->creq.mip_levels = srf->mip_levels[0];
1432 	rep->creq.drm_surface_flags = 0;
1433 	rep->creq.multisample_count = srf->multisample_count;
1434 	rep->creq.autogen_filter = srf->autogen_filter;
1435 	rep->creq.array_size = srf->array_size;
1436 	rep->creq.buffer_handle = backup_handle;
1437 	rep->creq.base_size = srf->base_size;
1438 	rep->crep.handle = user_srf->prime.base.hash.key;
1439 	rep->crep.backup_size = srf->res.backup_size;
1440 	rep->crep.buffer_handle = backup_handle;
1441 	rep->crep.buffer_map_handle =
1442 		drm_vma_node_offset_addr(&srf->res.backup->base.vma_node);
1443 	rep->crep.buffer_size = srf->res.backup->base.num_pages * PAGE_SIZE;
1444 
1445 out_bad_resource:
1446 	ttm_base_object_unref(&base);
1447 
1448 	return ret;
1449 }
1450 
1451 /**
1452  * vmw_surface_gb_priv_define - Define a private GB surface
1453  *
1454  * @dev:  Pointer to a struct drm_device
1455  * @user_accounting_size:  Used to track user-space memory usage, set
1456  *                         to 0 for kernel mode only memory
1457  * @svga3d_flags: SVGA3d surface flags for the device
1458  * @format: requested surface format
1459  * @for_scanout: true if inteded to be used for scanout buffer
1460  * @num_mip_levels:  number of MIP levels
1461  * @multisample_count:
1462  * @array_size: Surface array size.
1463  * @size: width, heigh, depth of the surface requested
1464  * @user_srf_out: allocated user_srf.  Set to NULL on failure.
1465  *
1466  * GB surfaces allocated by this function will not have a user mode handle, and
1467  * thus will only be visible to vmwgfx.  For optimization reasons the
1468  * surface may later be given a user mode handle by another function to make
1469  * it available to user mode drivers.
1470  */
1471 int vmw_surface_gb_priv_define(struct drm_device *dev,
1472 			       uint32_t user_accounting_size,
1473 			       uint32_t svga3d_flags,
1474 			       SVGA3dSurfaceFormat format,
1475 			       bool for_scanout,
1476 			       uint32_t num_mip_levels,
1477 			       uint32_t multisample_count,
1478 			       uint32_t array_size,
1479 			       struct drm_vmw_size size,
1480 			       struct vmw_surface **srf_out)
1481 {
1482 	struct vmw_private *dev_priv = vmw_priv(dev);
1483 	struct vmw_user_surface *user_srf;
1484 	struct ttm_operation_ctx ctx = {
1485 		.interruptible = true,
1486 		.no_wait_gpu = false
1487 	};
1488 	struct vmw_surface *srf;
1489 	int ret;
1490 	u32 num_layers;
1491 
1492 	*srf_out = NULL;
1493 
1494 	if (for_scanout) {
1495 		uint32_t max_width, max_height;
1496 
1497 		if (!svga3dsurface_is_screen_target_format(format)) {
1498 			DRM_ERROR("Invalid Screen Target surface format.");
1499 			return -EINVAL;
1500 		}
1501 
1502 		max_width = min(dev_priv->texture_max_width,
1503 				dev_priv->stdu_max_width);
1504 		max_height = min(dev_priv->texture_max_height,
1505 				 dev_priv->stdu_max_height);
1506 
1507 		if (size.width > max_width || size.height > max_height) {
1508 			DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u",
1509 				  size.width, size.height,
1510 				  max_width, max_height);
1511 			return -EINVAL;
1512 		}
1513 	} else {
1514 		const struct svga3d_surface_desc *desc;
1515 
1516 		desc = svga3dsurface_get_desc(format);
1517 		if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
1518 			DRM_ERROR("Invalid surface format.\n");
1519 			return -EINVAL;
1520 		}
1521 	}
1522 
1523 	/* array_size must be null for non-GL3 host. */
1524 	if (array_size > 0 && !dev_priv->has_dx) {
1525 		DRM_ERROR("Tried to create DX surface on non-DX host.\n");
1526 		return -EINVAL;
1527 	}
1528 
1529 	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
1530 	if (unlikely(ret != 0))
1531 		return ret;
1532 
1533 	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
1534 				   user_accounting_size, &ctx);
1535 	if (unlikely(ret != 0)) {
1536 		if (ret != -ERESTARTSYS)
1537 			DRM_ERROR("Out of graphics memory for surface"
1538 				  " creation.\n");
1539 		goto out_unlock;
1540 	}
1541 
1542 	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
1543 	if (unlikely(!user_srf)) {
1544 		ret = -ENOMEM;
1545 		goto out_no_user_srf;
1546 	}
1547 
1548 	*srf_out  = &user_srf->srf;
1549 	user_srf->size = user_accounting_size;
1550 	user_srf->prime.base.shareable = false;
1551 	user_srf->prime.base.tfile     = NULL;
1552 
1553 	srf = &user_srf->srf;
1554 	srf->flags             = svga3d_flags;
1555 	srf->format            = format;
1556 	srf->scanout           = for_scanout;
1557 	srf->mip_levels[0]     = num_mip_levels;
1558 	srf->num_sizes         = 1;
1559 	srf->sizes             = NULL;
1560 	srf->offsets           = NULL;
1561 	srf->base_size         = size;
1562 	srf->autogen_filter    = SVGA3D_TEX_FILTER_NONE;
1563 	srf->array_size        = array_size;
1564 	srf->multisample_count = multisample_count;
1565 
1566 	if (array_size)
1567 		num_layers = array_size;
1568 	else if (svga3d_flags & SVGA3D_SURFACE_CUBEMAP)
1569 		num_layers = SVGA3D_MAX_SURFACE_FACES;
1570 	else
1571 		num_layers = 1;
1572 
1573 	srf->res.backup_size   =
1574 		svga3dsurface_get_serialized_size(srf->format,
1575 						  srf->base_size,
1576 						  srf->mip_levels[0],
1577 						  num_layers);
1578 
1579 	if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
1580 		srf->res.backup_size += sizeof(SVGA3dDXSOState);
1581 
1582 	if (dev_priv->active_display_unit == vmw_du_screen_target &&
1583 	    for_scanout)
1584 		srf->flags |= SVGA3D_SURFACE_SCREENTARGET;
1585 
1586 	/*
1587 	 * From this point, the generic resource management functions
1588 	 * destroy the object on failure.
1589 	 */
1590 	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
1591 
1592 	ttm_read_unlock(&dev_priv->reservation_sem);
1593 	return ret;
1594 
1595 out_no_user_srf:
1596 	ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size);
1597 
1598 out_unlock:
1599 	ttm_read_unlock(&dev_priv->reservation_sem);
1600 	return ret;
1601 }
1602