xref: /linux/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
3  *
4  * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
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 "vmwgfx_bo.h"
29 #include "vmwgfx_drv.h"
30 #include "vmwgfx_resource_priv.h"
31 #include "vmwgfx_so.h"
32 #include "vmwgfx_binding.h"
33 #include "vmw_surface_cache.h"
34 #include "device_include/svga3d_surfacedefs.h"
35 
36 #include <drm/ttm/ttm_placement.h>
37 
38 #define SVGA3D_FLAGS_64(upper32, lower32) (((uint64_t)upper32 << 32) | lower32)
39 #define SVGA3D_FLAGS_UPPER_32(svga3d_flags) (svga3d_flags >> 32)
40 #define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
41 	(svga3d_flags & ((uint64_t)U32_MAX))
42 
43 /**
44  * struct vmw_user_surface - User-space visible surface resource
45  *
46  * @prime:          The TTM prime object.
47  * @base:           The TTM base object handling user-space visibility.
48  * @srf:            The surface metadata.
49  * @master:         Master of the creating client. Used for security check.
50  */
51 struct vmw_user_surface {
52 	struct ttm_prime_object prime;
53 	struct vmw_surface srf;
54 	struct drm_master *master;
55 };
56 
57 /**
58  * struct vmw_surface_offset - Backing store mip level offset info
59  *
60  * @face:           Surface face.
61  * @mip:            Mip level.
62  * @bo_offset:      Offset into backing store of this mip level.
63  *
64  */
65 struct vmw_surface_offset {
66 	uint32_t face;
67 	uint32_t mip;
68 	uint32_t bo_offset;
69 };
70 
71 /**
72  * struct vmw_surface_dirty - Surface dirty-tracker
73  * @cache: Cached layout information of the surface.
74  * @num_subres: Number of subresources.
75  * @boxes: Array of SVGA3dBoxes indicating dirty regions. One per subresource.
76  */
77 struct vmw_surface_dirty {
78 	struct vmw_surface_cache cache;
79 	u32 num_subres;
80 	SVGA3dBox boxes[];
81 };
82 
83 static void vmw_user_surface_free(struct vmw_resource *res);
84 static struct vmw_resource *
85 vmw_user_surface_base_to_res(struct ttm_base_object *base);
86 static int vmw_legacy_srf_bind(struct vmw_resource *res,
87 			       struct ttm_validate_buffer *val_buf);
88 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
89 				 bool readback,
90 				 struct ttm_validate_buffer *val_buf);
91 static int vmw_legacy_srf_create(struct vmw_resource *res);
92 static int vmw_legacy_srf_destroy(struct vmw_resource *res);
93 static int vmw_gb_surface_create(struct vmw_resource *res);
94 static int vmw_gb_surface_bind(struct vmw_resource *res,
95 			       struct ttm_validate_buffer *val_buf);
96 static int vmw_gb_surface_unbind(struct vmw_resource *res,
97 				 bool readback,
98 				 struct ttm_validate_buffer *val_buf);
99 static int vmw_gb_surface_destroy(struct vmw_resource *res);
100 static int
101 vmw_gb_surface_define_internal(struct drm_device *dev,
102 			       struct drm_vmw_gb_surface_create_ext_req *req,
103 			       struct drm_vmw_gb_surface_create_rep *rep,
104 			       struct drm_file *file_priv);
105 static int
106 vmw_gb_surface_reference_internal(struct drm_device *dev,
107 				  struct drm_vmw_surface_arg *req,
108 				  struct drm_vmw_gb_surface_ref_ext_rep *rep,
109 				  struct drm_file *file_priv);
110 
111 static void vmw_surface_dirty_free(struct vmw_resource *res);
112 static int vmw_surface_dirty_alloc(struct vmw_resource *res);
113 static int vmw_surface_dirty_sync(struct vmw_resource *res);
114 static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start,
115 					size_t end);
116 static int vmw_surface_clean(struct vmw_resource *res);
117 
118 static const struct vmw_user_resource_conv user_surface_conv = {
119 	.object_type = VMW_RES_SURFACE,
120 	.base_obj_to_res = vmw_user_surface_base_to_res,
121 	.res_free = vmw_user_surface_free
122 };
123 
124 const struct vmw_user_resource_conv *user_surface_converter =
125 	&user_surface_conv;
126 
127 static const struct vmw_res_func vmw_legacy_surface_func = {
128 	.res_type = vmw_res_surface,
129 	.needs_guest_memory = false,
130 	.may_evict = true,
131 	.prio = 1,
132 	.dirty_prio = 1,
133 	.type_name = "legacy surfaces",
134 	.domain = VMW_BO_DOMAIN_GMR,
135 	.busy_domain = VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
136 	.create = &vmw_legacy_srf_create,
137 	.destroy = &vmw_legacy_srf_destroy,
138 	.bind = &vmw_legacy_srf_bind,
139 	.unbind = &vmw_legacy_srf_unbind
140 };
141 
142 static const struct vmw_res_func vmw_gb_surface_func = {
143 	.res_type = vmw_res_surface,
144 	.needs_guest_memory = true,
145 	.may_evict = true,
146 	.prio = 1,
147 	.dirty_prio = 2,
148 	.type_name = "guest backed surfaces",
149 	.domain = VMW_BO_DOMAIN_MOB,
150 	.busy_domain = VMW_BO_DOMAIN_MOB,
151 	.create = vmw_gb_surface_create,
152 	.destroy = vmw_gb_surface_destroy,
153 	.bind = vmw_gb_surface_bind,
154 	.unbind = vmw_gb_surface_unbind,
155 	.dirty_alloc = vmw_surface_dirty_alloc,
156 	.dirty_free = vmw_surface_dirty_free,
157 	.dirty_sync = vmw_surface_dirty_sync,
158 	.dirty_range_add = vmw_surface_dirty_range_add,
159 	.clean = vmw_surface_clean,
160 };
161 
162 /*
163  * struct vmw_surface_dma - SVGA3D DMA command
164  */
165 struct vmw_surface_dma {
166 	SVGA3dCmdHeader header;
167 	SVGA3dCmdSurfaceDMA body;
168 	SVGA3dCopyBox cb;
169 	SVGA3dCmdSurfaceDMASuffix suffix;
170 };
171 
172 /*
173  * struct vmw_surface_define - SVGA3D Surface Define command
174  */
175 struct vmw_surface_define {
176 	SVGA3dCmdHeader header;
177 	SVGA3dCmdDefineSurface body;
178 };
179 
180 /*
181  * struct vmw_surface_destroy - SVGA3D Surface Destroy command
182  */
183 struct vmw_surface_destroy {
184 	SVGA3dCmdHeader header;
185 	SVGA3dCmdDestroySurface body;
186 };
187 
188 
189 /**
190  * vmw_surface_dma_size - Compute fifo size for a dma command.
191  *
192  * @srf: Pointer to a struct vmw_surface
193  *
194  * Computes the required size for a surface dma command for backup or
195  * restoration of the surface represented by @srf.
196  */
197 static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf)
198 {
199 	return srf->metadata.num_sizes * sizeof(struct vmw_surface_dma);
200 }
201 
202 
203 /**
204  * vmw_surface_define_size - Compute fifo size for a surface define command.
205  *
206  * @srf: Pointer to a struct vmw_surface
207  *
208  * Computes the required size for a surface define command for the definition
209  * of the surface represented by @srf.
210  */
211 static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf)
212 {
213 	return sizeof(struct vmw_surface_define) + srf->metadata.num_sizes *
214 		sizeof(SVGA3dSize);
215 }
216 
217 
218 /**
219  * vmw_surface_destroy_size - Compute fifo size for a surface destroy command.
220  *
221  * Computes the required size for a surface destroy command for the destruction
222  * of a hw surface.
223  */
224 static inline uint32_t vmw_surface_destroy_size(void)
225 {
226 	return sizeof(struct vmw_surface_destroy);
227 }
228 
229 /**
230  * vmw_surface_destroy_encode - Encode a surface_destroy command.
231  *
232  * @id: The surface id
233  * @cmd_space: Pointer to memory area in which the commands should be encoded.
234  */
235 static void vmw_surface_destroy_encode(uint32_t id,
236 				       void *cmd_space)
237 {
238 	struct vmw_surface_destroy *cmd = (struct vmw_surface_destroy *)
239 		cmd_space;
240 
241 	cmd->header.id = SVGA_3D_CMD_SURFACE_DESTROY;
242 	cmd->header.size = sizeof(cmd->body);
243 	cmd->body.sid = id;
244 }
245 
246 /**
247  * vmw_surface_define_encode - Encode a surface_define command.
248  *
249  * @srf: Pointer to a struct vmw_surface object.
250  * @cmd_space: Pointer to memory area in which the commands should be encoded.
251  */
252 static void vmw_surface_define_encode(const struct vmw_surface *srf,
253 				      void *cmd_space)
254 {
255 	struct vmw_surface_define *cmd = (struct vmw_surface_define *)
256 		cmd_space;
257 	struct drm_vmw_size *src_size;
258 	SVGA3dSize *cmd_size;
259 	uint32_t cmd_len;
260 	int i;
261 
262 	cmd_len = sizeof(cmd->body) + srf->metadata.num_sizes *
263 		sizeof(SVGA3dSize);
264 
265 	cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE;
266 	cmd->header.size = cmd_len;
267 	cmd->body.sid = srf->res.id;
268 	/*
269 	 * Downcast of surfaceFlags, was upcasted when received from user-space,
270 	 * since driver internally stores as 64 bit.
271 	 * For legacy surface define only 32 bit flag is supported.
272 	 */
273 	cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->metadata.flags;
274 	cmd->body.format = srf->metadata.format;
275 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
276 		cmd->body.face[i].numMipLevels = srf->metadata.mip_levels[i];
277 
278 	cmd += 1;
279 	cmd_size = (SVGA3dSize *) cmd;
280 	src_size = srf->metadata.sizes;
281 
282 	for (i = 0; i < srf->metadata.num_sizes; ++i, cmd_size++, src_size++) {
283 		cmd_size->width = src_size->width;
284 		cmd_size->height = src_size->height;
285 		cmd_size->depth = src_size->depth;
286 	}
287 }
288 
289 /**
290  * vmw_surface_dma_encode - Encode a surface_dma command.
291  *
292  * @srf: Pointer to a struct vmw_surface object.
293  * @cmd_space: Pointer to memory area in which the commands should be encoded.
294  * @ptr: Pointer to an SVGAGuestPtr indicating where the surface contents
295  * should be placed or read from.
296  * @to_surface: Boolean whether to DMA to the surface or from the surface.
297  */
298 static void vmw_surface_dma_encode(struct vmw_surface *srf,
299 				   void *cmd_space,
300 				   const SVGAGuestPtr *ptr,
301 				   bool to_surface)
302 {
303 	uint32_t i;
304 	struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space;
305 	const struct SVGA3dSurfaceDesc *desc =
306 		vmw_surface_get_desc(srf->metadata.format);
307 
308 	for (i = 0; i < srf->metadata.num_sizes; ++i) {
309 		SVGA3dCmdHeader *header = &cmd->header;
310 		SVGA3dCmdSurfaceDMA *body = &cmd->body;
311 		SVGA3dCopyBox *cb = &cmd->cb;
312 		SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix;
313 		const struct vmw_surface_offset *cur_offset = &srf->offsets[i];
314 		const struct drm_vmw_size *cur_size = &srf->metadata.sizes[i];
315 
316 		header->id = SVGA_3D_CMD_SURFACE_DMA;
317 		header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix);
318 
319 		body->guest.ptr = *ptr;
320 		body->guest.ptr.offset += cur_offset->bo_offset;
321 		body->guest.pitch = vmw_surface_calculate_pitch(desc, cur_size);
322 		body->host.sid = srf->res.id;
323 		body->host.face = cur_offset->face;
324 		body->host.mipmap = cur_offset->mip;
325 		body->transfer = ((to_surface) ?  SVGA3D_WRITE_HOST_VRAM :
326 				  SVGA3D_READ_HOST_VRAM);
327 		cb->x = 0;
328 		cb->y = 0;
329 		cb->z = 0;
330 		cb->srcx = 0;
331 		cb->srcy = 0;
332 		cb->srcz = 0;
333 		cb->w = cur_size->width;
334 		cb->h = cur_size->height;
335 		cb->d = cur_size->depth;
336 
337 		suffix->suffixSize = sizeof(*suffix);
338 		suffix->maximumOffset =
339 			vmw_surface_get_image_buffer_size(desc, cur_size,
340 							    body->guest.pitch);
341 		suffix->flags.discard = 0;
342 		suffix->flags.unsynchronized = 0;
343 		suffix->flags.reserved = 0;
344 		++cmd;
345 	}
346 };
347 
348 
349 /**
350  * vmw_hw_surface_destroy - destroy a Device surface
351  *
352  * @res:        Pointer to a struct vmw_resource embedded in a struct
353  *              vmw_surface.
354  *
355  * Destroys a the device surface associated with a struct vmw_surface if
356  * any, and adjusts resource count accordingly.
357  */
358 static void vmw_hw_surface_destroy(struct vmw_resource *res)
359 {
360 
361 	struct vmw_private *dev_priv = res->dev_priv;
362 	void *cmd;
363 
364 	if (res->func->destroy == vmw_gb_surface_destroy) {
365 		(void) vmw_gb_surface_destroy(res);
366 		return;
367 	}
368 
369 	if (res->id != -1) {
370 
371 		cmd = VMW_CMD_RESERVE(dev_priv, vmw_surface_destroy_size());
372 		if (unlikely(!cmd))
373 			return;
374 
375 		vmw_surface_destroy_encode(res->id, cmd);
376 		vmw_cmd_commit(dev_priv, vmw_surface_destroy_size());
377 
378 		/*
379 		 * used_memory_size_atomic, or separate lock
380 		 * to avoid taking dev_priv::cmdbuf_mutex in
381 		 * the destroy path.
382 		 */
383 
384 		mutex_lock(&dev_priv->cmdbuf_mutex);
385 		dev_priv->used_memory_size -= res->guest_memory_size;
386 		mutex_unlock(&dev_priv->cmdbuf_mutex);
387 	}
388 }
389 
390 /**
391  * vmw_legacy_srf_create - Create a device surface as part of the
392  * resource validation process.
393  *
394  * @res: Pointer to a struct vmw_surface.
395  *
396  * If the surface doesn't have a hw id.
397  *
398  * Returns -EBUSY if there wasn't sufficient device resources to
399  * complete the validation. Retry after freeing up resources.
400  *
401  * May return other errors if the kernel is out of guest resources.
402  */
403 static int vmw_legacy_srf_create(struct vmw_resource *res)
404 {
405 	struct vmw_private *dev_priv = res->dev_priv;
406 	struct vmw_surface *srf;
407 	uint32_t submit_size;
408 	uint8_t *cmd;
409 	int ret;
410 
411 	if (likely(res->id != -1))
412 		return 0;
413 
414 	srf = vmw_res_to_srf(res);
415 	if (unlikely(dev_priv->used_memory_size + res->guest_memory_size >=
416 		     dev_priv->memory_size))
417 		return -EBUSY;
418 
419 	/*
420 	 * Alloc id for the resource.
421 	 */
422 
423 	ret = vmw_resource_alloc_id(res);
424 	if (unlikely(ret != 0)) {
425 		DRM_ERROR("Failed to allocate a surface id.\n");
426 		goto out_no_id;
427 	}
428 
429 	if (unlikely(res->id >= SVGA3D_HB_MAX_SURFACE_IDS)) {
430 		ret = -EBUSY;
431 		goto out_no_fifo;
432 	}
433 
434 	/*
435 	 * Encode surface define- commands.
436 	 */
437 
438 	submit_size = vmw_surface_define_size(srf);
439 	cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
440 	if (unlikely(!cmd)) {
441 		ret = -ENOMEM;
442 		goto out_no_fifo;
443 	}
444 
445 	vmw_surface_define_encode(srf, cmd);
446 	vmw_cmd_commit(dev_priv, submit_size);
447 	vmw_fifo_resource_inc(dev_priv);
448 
449 	/*
450 	 * Surface memory usage accounting.
451 	 */
452 
453 	dev_priv->used_memory_size += res->guest_memory_size;
454 	return 0;
455 
456 out_no_fifo:
457 	vmw_resource_release_id(res);
458 out_no_id:
459 	return ret;
460 }
461 
462 /**
463  * vmw_legacy_srf_dma - Copy backup data to or from a legacy surface.
464  *
465  * @res:            Pointer to a struct vmw_res embedded in a struct
466  *                  vmw_surface.
467  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
468  *                  information about the backup buffer.
469  * @bind:           Boolean wether to DMA to the surface.
470  *
471  * Transfer backup data to or from a legacy surface as part of the
472  * validation process.
473  * May return other errors if the kernel is out of guest resources.
474  * The backup buffer will be fenced or idle upon successful completion,
475  * and if the surface needs persistent backup storage, the backup buffer
476  * will also be returned reserved iff @bind is true.
477  */
478 static int vmw_legacy_srf_dma(struct vmw_resource *res,
479 			      struct ttm_validate_buffer *val_buf,
480 			      bool bind)
481 {
482 	SVGAGuestPtr ptr;
483 	struct vmw_fence_obj *fence;
484 	uint32_t submit_size;
485 	struct vmw_surface *srf = vmw_res_to_srf(res);
486 	uint8_t *cmd;
487 	struct vmw_private *dev_priv = res->dev_priv;
488 
489 	BUG_ON(!val_buf->bo);
490 	submit_size = vmw_surface_dma_size(srf);
491 	cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
492 	if (unlikely(!cmd))
493 		return -ENOMEM;
494 
495 	vmw_bo_get_guest_ptr(val_buf->bo, &ptr);
496 	vmw_surface_dma_encode(srf, cmd, &ptr, bind);
497 
498 	vmw_cmd_commit(dev_priv, submit_size);
499 
500 	/*
501 	 * Create a fence object and fence the backup buffer.
502 	 */
503 
504 	(void) vmw_execbuf_fence_commands(NULL, dev_priv,
505 					  &fence, NULL);
506 
507 	vmw_bo_fence_single(val_buf->bo, fence);
508 
509 	if (likely(fence != NULL))
510 		vmw_fence_obj_unreference(&fence);
511 
512 	return 0;
513 }
514 
515 /**
516  * vmw_legacy_srf_bind - Perform a legacy surface bind as part of the
517  *                       surface validation process.
518  *
519  * @res:            Pointer to a struct vmw_res embedded in a struct
520  *                  vmw_surface.
521  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
522  *                  information about the backup buffer.
523  *
524  * This function will copy backup data to the surface if the
525  * backup buffer is dirty.
526  */
527 static int vmw_legacy_srf_bind(struct vmw_resource *res,
528 			       struct ttm_validate_buffer *val_buf)
529 {
530 	if (!res->guest_memory_dirty)
531 		return 0;
532 
533 	return vmw_legacy_srf_dma(res, val_buf, true);
534 }
535 
536 
537 /**
538  * vmw_legacy_srf_unbind - Perform a legacy surface unbind as part of the
539  *                         surface eviction process.
540  *
541  * @res:            Pointer to a struct vmw_res embedded in a struct
542  *                  vmw_surface.
543  * @readback:       Readback - only true if dirty
544  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
545  *                  information about the backup buffer.
546  *
547  * This function will copy backup data from the surface.
548  */
549 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
550 				 bool readback,
551 				 struct ttm_validate_buffer *val_buf)
552 {
553 	if (unlikely(readback))
554 		return vmw_legacy_srf_dma(res, val_buf, false);
555 	return 0;
556 }
557 
558 /**
559  * vmw_legacy_srf_destroy - Destroy a device surface as part of a
560  *                          resource eviction process.
561  *
562  * @res:            Pointer to a struct vmw_res embedded in a struct
563  *                  vmw_surface.
564  */
565 static int vmw_legacy_srf_destroy(struct vmw_resource *res)
566 {
567 	struct vmw_private *dev_priv = res->dev_priv;
568 	uint32_t submit_size;
569 	uint8_t *cmd;
570 
571 	BUG_ON(res->id == -1);
572 
573 	/*
574 	 * Encode the dma- and surface destroy commands.
575 	 */
576 
577 	submit_size = vmw_surface_destroy_size();
578 	cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
579 	if (unlikely(!cmd))
580 		return -ENOMEM;
581 
582 	vmw_surface_destroy_encode(res->id, cmd);
583 	vmw_cmd_commit(dev_priv, submit_size);
584 
585 	/*
586 	 * Surface memory usage accounting.
587 	 */
588 
589 	dev_priv->used_memory_size -= res->guest_memory_size;
590 
591 	/*
592 	 * Release the surface ID.
593 	 */
594 
595 	vmw_resource_release_id(res);
596 	vmw_fifo_resource_dec(dev_priv);
597 
598 	return 0;
599 }
600 
601 
602 /**
603  * vmw_surface_init - initialize a struct vmw_surface
604  *
605  * @dev_priv:       Pointer to a device private struct.
606  * @srf:            Pointer to the struct vmw_surface to initialize.
607  * @res_free:       Pointer to a resource destructor used to free
608  *                  the object.
609  */
610 static int vmw_surface_init(struct vmw_private *dev_priv,
611 			    struct vmw_surface *srf,
612 			    void (*res_free) (struct vmw_resource *res))
613 {
614 	int ret;
615 	struct vmw_resource *res = &srf->res;
616 
617 	BUG_ON(!res_free);
618 	ret = vmw_resource_init(dev_priv, res, true, res_free,
619 				(dev_priv->has_mob) ? &vmw_gb_surface_func :
620 				&vmw_legacy_surface_func);
621 
622 	if (unlikely(ret != 0)) {
623 		res_free(res);
624 		return ret;
625 	}
626 
627 	/*
628 	 * The surface won't be visible to hardware until a
629 	 * surface validate.
630 	 */
631 
632 	INIT_LIST_HEAD(&srf->view_list);
633 	res->hw_destroy = vmw_hw_surface_destroy;
634 	return ret;
635 }
636 
637 /**
638  * vmw_user_surface_base_to_res - TTM base object to resource converter for
639  *                                user visible surfaces
640  *
641  * @base:           Pointer to a TTM base object
642  *
643  * Returns the struct vmw_resource embedded in a struct vmw_surface
644  * for the user-visible object identified by the TTM base object @base.
645  */
646 static struct vmw_resource *
647 vmw_user_surface_base_to_res(struct ttm_base_object *base)
648 {
649 	return &(container_of(base, struct vmw_user_surface,
650 			      prime.base)->srf.res);
651 }
652 
653 /**
654  * vmw_user_surface_free - User visible surface resource destructor
655  *
656  * @res:            A struct vmw_resource embedded in a struct vmw_surface.
657  */
658 static void vmw_user_surface_free(struct vmw_resource *res)
659 {
660 	struct vmw_surface *srf = vmw_res_to_srf(res);
661 	struct vmw_user_surface *user_srf =
662 	    container_of(srf, struct vmw_user_surface, srf);
663 
664 	WARN_ON_ONCE(res->dirty);
665 	if (user_srf->master)
666 		drm_master_put(&user_srf->master);
667 	kfree(srf->offsets);
668 	kfree(srf->metadata.sizes);
669 	kfree(srf->snooper.image);
670 	ttm_prime_object_kfree(user_srf, prime);
671 }
672 
673 /**
674  * vmw_user_surface_base_release - User visible surface TTM base object destructor
675  *
676  * @p_base:         Pointer to a pointer to a TTM base object
677  *                  embedded in a struct vmw_user_surface.
678  *
679  * Drops the base object's reference on its resource, and the
680  * pointer pointed to by *p_base is set to NULL.
681  */
682 static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
683 {
684 	struct ttm_base_object *base = *p_base;
685 	struct vmw_user_surface *user_srf =
686 	    container_of(base, struct vmw_user_surface, prime.base);
687 	struct vmw_resource *res = &user_srf->srf.res;
688 
689 	if (res->guest_memory_bo)
690 		drm_gem_object_put(&res->guest_memory_bo->tbo.base);
691 
692 	*p_base = NULL;
693 	vmw_resource_unreference(&res);
694 }
695 
696 /**
697  * vmw_surface_destroy_ioctl - Ioctl function implementing
698  *                                  the user surface destroy functionality.
699  *
700  * @dev:            Pointer to a struct drm_device.
701  * @data:           Pointer to data copied from / to user-space.
702  * @file_priv:      Pointer to a drm file private structure.
703  */
704 int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
705 			      struct drm_file *file_priv)
706 {
707 	struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
708 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
709 
710 	return ttm_ref_object_base_unref(tfile, arg->sid);
711 }
712 
713 /**
714  * vmw_surface_define_ioctl - Ioctl function implementing
715  *                                  the user surface define functionality.
716  *
717  * @dev:            Pointer to a struct drm_device.
718  * @data:           Pointer to data copied from / to user-space.
719  * @file_priv:      Pointer to a drm file private structure.
720  */
721 int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
722 			     struct drm_file *file_priv)
723 {
724 	struct vmw_private *dev_priv = vmw_priv(dev);
725 	struct vmw_user_surface *user_srf;
726 	struct vmw_surface *srf;
727 	struct vmw_surface_metadata *metadata;
728 	struct vmw_resource *res;
729 	struct vmw_resource *tmp;
730 	union drm_vmw_surface_create_arg *arg =
731 	    (union drm_vmw_surface_create_arg *)data;
732 	struct drm_vmw_surface_create_req *req = &arg->req;
733 	struct drm_vmw_surface_arg *rep = &arg->rep;
734 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
735 	int ret;
736 	int i, j;
737 	uint32_t cur_bo_offset;
738 	struct drm_vmw_size *cur_size;
739 	struct vmw_surface_offset *cur_offset;
740 	uint32_t num_sizes;
741 	const SVGA3dSurfaceDesc *desc;
742 
743 	num_sizes = 0;
744 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
745 		if (req->mip_levels[i] > DRM_VMW_MAX_MIP_LEVELS)
746 			return -EINVAL;
747 		num_sizes += req->mip_levels[i];
748 	}
749 
750 	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES * DRM_VMW_MAX_MIP_LEVELS ||
751 	    num_sizes == 0)
752 		return -EINVAL;
753 
754 	desc = vmw_surface_get_desc(req->format);
755 	if (unlikely(desc->blockDesc == SVGA3DBLOCKDESC_NONE)) {
756 		VMW_DEBUG_USER("Invalid format %d for surface creation.\n",
757 			       req->format);
758 		return -EINVAL;
759 	}
760 
761 	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
762 	if (unlikely(!user_srf)) {
763 		ret = -ENOMEM;
764 		goto out_unlock;
765 	}
766 
767 	srf = &user_srf->srf;
768 	metadata = &srf->metadata;
769 	res = &srf->res;
770 
771 	/* Driver internally stores as 64-bit flags */
772 	metadata->flags = (SVGA3dSurfaceAllFlags)req->flags;
773 	metadata->format = req->format;
774 	metadata->scanout = req->scanout;
775 
776 	memcpy(metadata->mip_levels, req->mip_levels,
777 	       sizeof(metadata->mip_levels));
778 	metadata->num_sizes = num_sizes;
779 	metadata->sizes =
780 		memdup_user((struct drm_vmw_size __user *)(unsigned long)
781 			    req->size_addr,
782 			    sizeof(*metadata->sizes) * metadata->num_sizes);
783 	if (IS_ERR(metadata->sizes)) {
784 		ret = PTR_ERR(metadata->sizes);
785 		goto out_no_sizes;
786 	}
787 	srf->offsets = kmalloc_array(metadata->num_sizes, sizeof(*srf->offsets),
788 				     GFP_KERNEL);
789 	if (unlikely(!srf->offsets)) {
790 		ret = -ENOMEM;
791 		goto out_no_offsets;
792 	}
793 
794 	metadata->base_size = *srf->metadata.sizes;
795 	metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE;
796 	metadata->multisample_count = 0;
797 	metadata->multisample_pattern = SVGA3D_MS_PATTERN_NONE;
798 	metadata->quality_level = SVGA3D_MS_QUALITY_NONE;
799 
800 	cur_bo_offset = 0;
801 	cur_offset = srf->offsets;
802 	cur_size = metadata->sizes;
803 
804 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
805 		for (j = 0; j < metadata->mip_levels[i]; ++j) {
806 			uint32_t stride = vmw_surface_calculate_pitch(
807 						  desc, cur_size);
808 
809 			cur_offset->face = i;
810 			cur_offset->mip = j;
811 			cur_offset->bo_offset = cur_bo_offset;
812 			cur_bo_offset += vmw_surface_get_image_buffer_size
813 				(desc, cur_size, stride);
814 			++cur_offset;
815 			++cur_size;
816 		}
817 	}
818 	res->guest_memory_size = cur_bo_offset;
819 	if (metadata->scanout &&
820 	    metadata->num_sizes == 1 &&
821 	    metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
822 	    metadata->sizes[0].height == VMW_CURSOR_SNOOP_HEIGHT &&
823 	    metadata->format == VMW_CURSOR_SNOOP_FORMAT) {
824 		const struct SVGA3dSurfaceDesc *desc =
825 			vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
826 		const u32 cursor_size_bytes = VMW_CURSOR_SNOOP_WIDTH *
827 					      VMW_CURSOR_SNOOP_HEIGHT *
828 					      desc->pitchBytesPerBlock;
829 		srf->snooper.image = kzalloc(cursor_size_bytes, GFP_KERNEL);
830 		if (!srf->snooper.image) {
831 			DRM_ERROR("Failed to allocate cursor_image\n");
832 			ret = -ENOMEM;
833 			goto out_no_copy;
834 		}
835 	} else {
836 		srf->snooper.image = NULL;
837 	}
838 
839 	user_srf->prime.base.shareable = false;
840 	user_srf->prime.base.tfile = NULL;
841 	if (drm_is_primary_client(file_priv))
842 		user_srf->master = drm_file_get_master(file_priv);
843 
844 	/**
845 	 * From this point, the generic resource management functions
846 	 * destroy the object on failure.
847 	 */
848 
849 	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
850 	if (unlikely(ret != 0))
851 		goto out_unlock;
852 
853 	/*
854 	 * A gb-aware client referencing a shared surface will
855 	 * expect a backup buffer to be present.
856 	 */
857 	if (dev_priv->has_mob && req->shareable) {
858 		uint32_t backup_handle;
859 
860 		ret = vmw_gem_object_create_with_handle(dev_priv,
861 							file_priv,
862 							res->guest_memory_size,
863 							&backup_handle,
864 							&res->guest_memory_bo);
865 		if (unlikely(ret != 0)) {
866 			vmw_resource_unreference(&res);
867 			goto out_unlock;
868 		}
869 		vmw_bo_reference(res->guest_memory_bo);
870 		/*
871 		 * We don't expose the handle to the userspace and surface
872 		 * already holds a gem reference
873 		 */
874 		drm_gem_handle_delete(file_priv, backup_handle);
875 	}
876 
877 	tmp = vmw_resource_reference(&srf->res);
878 	ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
879 				    req->shareable, VMW_RES_SURFACE,
880 				    &vmw_user_surface_base_release);
881 
882 	if (unlikely(ret != 0)) {
883 		vmw_resource_unreference(&tmp);
884 		vmw_resource_unreference(&res);
885 		goto out_unlock;
886 	}
887 
888 	rep->sid = user_srf->prime.base.handle;
889 	vmw_resource_unreference(&res);
890 
891 	return 0;
892 out_no_copy:
893 	kfree(srf->offsets);
894 out_no_offsets:
895 	kfree(metadata->sizes);
896 out_no_sizes:
897 	ttm_prime_object_kfree(user_srf, prime);
898 out_unlock:
899 	return ret;
900 }
901 
902 
903 static int
904 vmw_surface_handle_reference(struct vmw_private *dev_priv,
905 			     struct drm_file *file_priv,
906 			     uint32_t u_handle,
907 			     enum drm_vmw_handle_type handle_type,
908 			     struct ttm_base_object **base_p)
909 {
910 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
911 	struct vmw_user_surface *user_srf;
912 	uint32_t handle;
913 	struct ttm_base_object *base;
914 	int ret;
915 
916 	if (handle_type == DRM_VMW_HANDLE_PRIME) {
917 		ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
918 		if (unlikely(ret != 0))
919 			return ret;
920 	} else {
921 		handle = u_handle;
922 	}
923 
924 	ret = -EINVAL;
925 	base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle);
926 	if (unlikely(!base)) {
927 		VMW_DEBUG_USER("Could not find surface to reference.\n");
928 		goto out_no_lookup;
929 	}
930 
931 	if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) {
932 		VMW_DEBUG_USER("Referenced object is not a surface.\n");
933 		goto out_bad_resource;
934 	}
935 	if (handle_type != DRM_VMW_HANDLE_PRIME) {
936 		bool require_exist = false;
937 
938 		user_srf = container_of(base, struct vmw_user_surface,
939 					prime.base);
940 
941 		/* Error out if we are unauthenticated primary */
942 		if (drm_is_primary_client(file_priv) &&
943 		    !file_priv->authenticated) {
944 			ret = -EACCES;
945 			goto out_bad_resource;
946 		}
947 
948 		/*
949 		 * Make sure the surface creator has the same
950 		 * authenticating master, or is already registered with us.
951 		 */
952 		if (drm_is_primary_client(file_priv) &&
953 		    user_srf->master != file_priv->master)
954 			require_exist = true;
955 
956 		if (unlikely(drm_is_render_client(file_priv)))
957 			require_exist = true;
958 
959 		ret = ttm_ref_object_add(tfile, base, NULL, require_exist);
960 		if (unlikely(ret != 0)) {
961 			DRM_ERROR("Could not add a reference to a surface.\n");
962 			goto out_bad_resource;
963 		}
964 	}
965 
966 	*base_p = base;
967 	return 0;
968 
969 out_bad_resource:
970 	ttm_base_object_unref(&base);
971 out_no_lookup:
972 	if (handle_type == DRM_VMW_HANDLE_PRIME)
973 		(void) ttm_ref_object_base_unref(tfile, handle);
974 
975 	return ret;
976 }
977 
978 /**
979  * vmw_surface_reference_ioctl - Ioctl function implementing
980  *                                  the user surface reference functionality.
981  *
982  * @dev:            Pointer to a struct drm_device.
983  * @data:           Pointer to data copied from / to user-space.
984  * @file_priv:      Pointer to a drm file private structure.
985  */
986 int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
987 				struct drm_file *file_priv)
988 {
989 	struct vmw_private *dev_priv = vmw_priv(dev);
990 	union drm_vmw_surface_reference_arg *arg =
991 	    (union drm_vmw_surface_reference_arg *)data;
992 	struct drm_vmw_surface_arg *req = &arg->req;
993 	struct drm_vmw_surface_create_req *rep = &arg->rep;
994 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
995 	struct vmw_surface *srf;
996 	struct vmw_user_surface *user_srf;
997 	struct drm_vmw_size __user *user_sizes;
998 	struct ttm_base_object *base;
999 	int ret;
1000 
1001 	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
1002 					   req->handle_type, &base);
1003 	if (unlikely(ret != 0))
1004 		return ret;
1005 
1006 	user_srf = container_of(base, struct vmw_user_surface, prime.base);
1007 	srf = &user_srf->srf;
1008 
1009 	/* Downcast of flags when sending back to user space */
1010 	rep->flags = (uint32_t)srf->metadata.flags;
1011 	rep->format = srf->metadata.format;
1012 	memcpy(rep->mip_levels, srf->metadata.mip_levels,
1013 	       sizeof(srf->metadata.mip_levels));
1014 	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
1015 	    rep->size_addr;
1016 
1017 	if (user_sizes)
1018 		ret = copy_to_user(user_sizes, &srf->metadata.base_size,
1019 				   sizeof(srf->metadata.base_size));
1020 	if (unlikely(ret != 0)) {
1021 		VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes,
1022 			       srf->metadata.num_sizes);
1023 		ttm_ref_object_base_unref(tfile, base->handle);
1024 		ret = -EFAULT;
1025 	}
1026 
1027 	ttm_base_object_unref(&base);
1028 
1029 	return ret;
1030 }
1031 
1032 /**
1033  * vmw_gb_surface_create - Encode a surface_define command.
1034  *
1035  * @res:        Pointer to a struct vmw_resource embedded in a struct
1036  *              vmw_surface.
1037  */
1038 static int vmw_gb_surface_create(struct vmw_resource *res)
1039 {
1040 	struct vmw_private *dev_priv = res->dev_priv;
1041 	struct vmw_surface *srf = vmw_res_to_srf(res);
1042 	struct vmw_surface_metadata *metadata = &srf->metadata;
1043 	uint32_t cmd_len, cmd_id, submit_len;
1044 	int ret;
1045 	struct {
1046 		SVGA3dCmdHeader header;
1047 		SVGA3dCmdDefineGBSurface body;
1048 	} *cmd;
1049 	struct {
1050 		SVGA3dCmdHeader header;
1051 		SVGA3dCmdDefineGBSurface_v2 body;
1052 	} *cmd2;
1053 	struct {
1054 		SVGA3dCmdHeader header;
1055 		SVGA3dCmdDefineGBSurface_v3 body;
1056 	} *cmd3;
1057 	struct {
1058 		SVGA3dCmdHeader header;
1059 		SVGA3dCmdDefineGBSurface_v4 body;
1060 	} *cmd4;
1061 
1062 	if (likely(res->id != -1))
1063 		return 0;
1064 
1065 	vmw_fifo_resource_inc(dev_priv);
1066 	ret = vmw_resource_alloc_id(res);
1067 	if (unlikely(ret != 0)) {
1068 		DRM_ERROR("Failed to allocate a surface id.\n");
1069 		goto out_no_id;
1070 	}
1071 
1072 	if (unlikely(res->id >= VMWGFX_NUM_GB_SURFACE)) {
1073 		ret = -EBUSY;
1074 		goto out_no_fifo;
1075 	}
1076 
1077 	if (has_sm5_context(dev_priv) && metadata->array_size > 0) {
1078 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V4;
1079 		cmd_len = sizeof(cmd4->body);
1080 		submit_len = sizeof(*cmd4);
1081 	} else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) {
1082 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3;
1083 		cmd_len = sizeof(cmd3->body);
1084 		submit_len = sizeof(*cmd3);
1085 	} else if (metadata->array_size > 0) {
1086 		/* VMW_SM_4 support verified at creation time. */
1087 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2;
1088 		cmd_len = sizeof(cmd2->body);
1089 		submit_len = sizeof(*cmd2);
1090 	} else {
1091 		cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE;
1092 		cmd_len = sizeof(cmd->body);
1093 		submit_len = sizeof(*cmd);
1094 	}
1095 
1096 	cmd = VMW_CMD_RESERVE(dev_priv, submit_len);
1097 	cmd2 = (typeof(cmd2))cmd;
1098 	cmd3 = (typeof(cmd3))cmd;
1099 	cmd4 = (typeof(cmd4))cmd;
1100 	if (unlikely(!cmd)) {
1101 		ret = -ENOMEM;
1102 		goto out_no_fifo;
1103 	}
1104 
1105 	if (has_sm5_context(dev_priv) && metadata->array_size > 0) {
1106 		cmd4->header.id = cmd_id;
1107 		cmd4->header.size = cmd_len;
1108 		cmd4->body.sid = srf->res.id;
1109 		cmd4->body.surfaceFlags = metadata->flags;
1110 		cmd4->body.format = metadata->format;
1111 		cmd4->body.numMipLevels = metadata->mip_levels[0];
1112 		cmd4->body.multisampleCount = metadata->multisample_count;
1113 		cmd4->body.multisamplePattern = metadata->multisample_pattern;
1114 		cmd4->body.qualityLevel = metadata->quality_level;
1115 		cmd4->body.autogenFilter = metadata->autogen_filter;
1116 		cmd4->body.size.width = metadata->base_size.width;
1117 		cmd4->body.size.height = metadata->base_size.height;
1118 		cmd4->body.size.depth = metadata->base_size.depth;
1119 		cmd4->body.arraySize = metadata->array_size;
1120 		cmd4->body.bufferByteStride = metadata->buffer_byte_stride;
1121 	} else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) {
1122 		cmd3->header.id = cmd_id;
1123 		cmd3->header.size = cmd_len;
1124 		cmd3->body.sid = srf->res.id;
1125 		cmd3->body.surfaceFlags = metadata->flags;
1126 		cmd3->body.format = metadata->format;
1127 		cmd3->body.numMipLevels = metadata->mip_levels[0];
1128 		cmd3->body.multisampleCount = metadata->multisample_count;
1129 		cmd3->body.multisamplePattern = metadata->multisample_pattern;
1130 		cmd3->body.qualityLevel = metadata->quality_level;
1131 		cmd3->body.autogenFilter = metadata->autogen_filter;
1132 		cmd3->body.size.width = metadata->base_size.width;
1133 		cmd3->body.size.height = metadata->base_size.height;
1134 		cmd3->body.size.depth = metadata->base_size.depth;
1135 		cmd3->body.arraySize = metadata->array_size;
1136 	} else if (metadata->array_size > 0) {
1137 		cmd2->header.id = cmd_id;
1138 		cmd2->header.size = cmd_len;
1139 		cmd2->body.sid = srf->res.id;
1140 		cmd2->body.surfaceFlags = metadata->flags;
1141 		cmd2->body.format = metadata->format;
1142 		cmd2->body.numMipLevels = metadata->mip_levels[0];
1143 		cmd2->body.multisampleCount = metadata->multisample_count;
1144 		cmd2->body.autogenFilter = metadata->autogen_filter;
1145 		cmd2->body.size.width = metadata->base_size.width;
1146 		cmd2->body.size.height = metadata->base_size.height;
1147 		cmd2->body.size.depth = metadata->base_size.depth;
1148 		cmd2->body.arraySize = metadata->array_size;
1149 	} else {
1150 		cmd->header.id = cmd_id;
1151 		cmd->header.size = cmd_len;
1152 		cmd->body.sid = srf->res.id;
1153 		cmd->body.surfaceFlags = metadata->flags;
1154 		cmd->body.format = metadata->format;
1155 		cmd->body.numMipLevels = metadata->mip_levels[0];
1156 		cmd->body.multisampleCount = metadata->multisample_count;
1157 		cmd->body.autogenFilter = metadata->autogen_filter;
1158 		cmd->body.size.width = metadata->base_size.width;
1159 		cmd->body.size.height = metadata->base_size.height;
1160 		cmd->body.size.depth = metadata->base_size.depth;
1161 	}
1162 
1163 	vmw_cmd_commit(dev_priv, submit_len);
1164 
1165 	return 0;
1166 
1167 out_no_fifo:
1168 	vmw_resource_release_id(res);
1169 out_no_id:
1170 	vmw_fifo_resource_dec(dev_priv);
1171 	return ret;
1172 }
1173 
1174 
1175 static int vmw_gb_surface_bind(struct vmw_resource *res,
1176 			       struct ttm_validate_buffer *val_buf)
1177 {
1178 	struct vmw_private *dev_priv = res->dev_priv;
1179 	struct {
1180 		SVGA3dCmdHeader header;
1181 		SVGA3dCmdBindGBSurface body;
1182 	} *cmd1;
1183 	struct {
1184 		SVGA3dCmdHeader header;
1185 		SVGA3dCmdUpdateGBSurface body;
1186 	} *cmd2;
1187 	uint32_t submit_size;
1188 	struct ttm_buffer_object *bo = val_buf->bo;
1189 
1190 	BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
1191 
1192 	submit_size = sizeof(*cmd1) + (res->guest_memory_dirty ? sizeof(*cmd2) : 0);
1193 
1194 	cmd1 = VMW_CMD_RESERVE(dev_priv, submit_size);
1195 	if (unlikely(!cmd1))
1196 		return -ENOMEM;
1197 
1198 	cmd1->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1199 	cmd1->header.size = sizeof(cmd1->body);
1200 	cmd1->body.sid = res->id;
1201 	cmd1->body.mobid = bo->resource->start;
1202 	if (res->guest_memory_dirty) {
1203 		cmd2 = (void *) &cmd1[1];
1204 		cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_SURFACE;
1205 		cmd2->header.size = sizeof(cmd2->body);
1206 		cmd2->body.sid = res->id;
1207 	}
1208 	vmw_cmd_commit(dev_priv, submit_size);
1209 
1210 	if (res->guest_memory_bo->dirty && res->guest_memory_dirty) {
1211 		/* We've just made a full upload. Cear dirty regions. */
1212 		vmw_bo_dirty_clear_res(res);
1213 	}
1214 
1215 	res->guest_memory_dirty = false;
1216 
1217 	return 0;
1218 }
1219 
1220 static int vmw_gb_surface_unbind(struct vmw_resource *res,
1221 				 bool readback,
1222 				 struct ttm_validate_buffer *val_buf)
1223 {
1224 	struct vmw_private *dev_priv = res->dev_priv;
1225 	struct ttm_buffer_object *bo = val_buf->bo;
1226 	struct vmw_fence_obj *fence;
1227 
1228 	struct {
1229 		SVGA3dCmdHeader header;
1230 		SVGA3dCmdReadbackGBSurface body;
1231 	} *cmd1;
1232 	struct {
1233 		SVGA3dCmdHeader header;
1234 		SVGA3dCmdInvalidateGBSurface body;
1235 	} *cmd2;
1236 	struct {
1237 		SVGA3dCmdHeader header;
1238 		SVGA3dCmdBindGBSurface body;
1239 	} *cmd3;
1240 	uint32_t submit_size;
1241 	uint8_t *cmd;
1242 
1243 
1244 	BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
1245 
1246 	submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2));
1247 	cmd = VMW_CMD_RESERVE(dev_priv, submit_size);
1248 	if (unlikely(!cmd))
1249 		return -ENOMEM;
1250 
1251 	if (readback) {
1252 		cmd1 = (void *) cmd;
1253 		cmd1->header.id = SVGA_3D_CMD_READBACK_GB_SURFACE;
1254 		cmd1->header.size = sizeof(cmd1->body);
1255 		cmd1->body.sid = res->id;
1256 		cmd3 = (void *) &cmd1[1];
1257 	} else {
1258 		cmd2 = (void *) cmd;
1259 		cmd2->header.id = SVGA_3D_CMD_INVALIDATE_GB_SURFACE;
1260 		cmd2->header.size = sizeof(cmd2->body);
1261 		cmd2->body.sid = res->id;
1262 		cmd3 = (void *) &cmd2[1];
1263 	}
1264 
1265 	cmd3->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
1266 	cmd3->header.size = sizeof(cmd3->body);
1267 	cmd3->body.sid = res->id;
1268 	cmd3->body.mobid = SVGA3D_INVALID_ID;
1269 
1270 	vmw_cmd_commit(dev_priv, submit_size);
1271 
1272 	/*
1273 	 * Create a fence object and fence the backup buffer.
1274 	 */
1275 
1276 	(void) vmw_execbuf_fence_commands(NULL, dev_priv,
1277 					  &fence, NULL);
1278 
1279 	vmw_bo_fence_single(val_buf->bo, fence);
1280 
1281 	if (likely(fence != NULL))
1282 		vmw_fence_obj_unreference(&fence);
1283 
1284 	return 0;
1285 }
1286 
1287 static int vmw_gb_surface_destroy(struct vmw_resource *res)
1288 {
1289 	struct vmw_private *dev_priv = res->dev_priv;
1290 	struct vmw_surface *srf = vmw_res_to_srf(res);
1291 	struct {
1292 		SVGA3dCmdHeader header;
1293 		SVGA3dCmdDestroyGBSurface body;
1294 	} *cmd;
1295 
1296 	if (likely(res->id == -1))
1297 		return 0;
1298 
1299 	mutex_lock(&dev_priv->binding_mutex);
1300 	vmw_view_surface_list_destroy(dev_priv, &srf->view_list);
1301 	vmw_binding_res_list_scrub(&res->binding_head);
1302 
1303 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
1304 	if (unlikely(!cmd)) {
1305 		mutex_unlock(&dev_priv->binding_mutex);
1306 		return -ENOMEM;
1307 	}
1308 
1309 	cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SURFACE;
1310 	cmd->header.size = sizeof(cmd->body);
1311 	cmd->body.sid = res->id;
1312 	vmw_cmd_commit(dev_priv, sizeof(*cmd));
1313 	mutex_unlock(&dev_priv->binding_mutex);
1314 	vmw_resource_release_id(res);
1315 	vmw_fifo_resource_dec(dev_priv);
1316 
1317 	return 0;
1318 }
1319 
1320 /**
1321  * vmw_gb_surface_define_ioctl - Ioctl function implementing
1322  * the user surface define functionality.
1323  *
1324  * @dev: Pointer to a struct drm_device.
1325  * @data: Pointer to data copied from / to user-space.
1326  * @file_priv: Pointer to a drm file private structure.
1327  */
1328 int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
1329 				struct drm_file *file_priv)
1330 {
1331 	union drm_vmw_gb_surface_create_arg *arg =
1332 	    (union drm_vmw_gb_surface_create_arg *)data;
1333 	struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
1334 	struct drm_vmw_gb_surface_create_ext_req req_ext;
1335 
1336 	req_ext.base = arg->req;
1337 	req_ext.version = drm_vmw_gb_surface_v1;
1338 	req_ext.svga3d_flags_upper_32_bits = 0;
1339 	req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE;
1340 	req_ext.quality_level = SVGA3D_MS_QUALITY_NONE;
1341 	req_ext.buffer_byte_stride = 0;
1342 	req_ext.must_be_zero = 0;
1343 
1344 	return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv);
1345 }
1346 
1347 /**
1348  * vmw_gb_surface_reference_ioctl - Ioctl function implementing
1349  * the user surface reference functionality.
1350  *
1351  * @dev: Pointer to a struct drm_device.
1352  * @data: Pointer to data copied from / to user-space.
1353  * @file_priv: Pointer to a drm file private structure.
1354  */
1355 int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data,
1356 				   struct drm_file *file_priv)
1357 {
1358 	union drm_vmw_gb_surface_reference_arg *arg =
1359 	    (union drm_vmw_gb_surface_reference_arg *)data;
1360 	struct drm_vmw_surface_arg *req = &arg->req;
1361 	struct drm_vmw_gb_surface_ref_rep *rep = &arg->rep;
1362 	struct drm_vmw_gb_surface_ref_ext_rep rep_ext;
1363 	int ret;
1364 
1365 	ret = vmw_gb_surface_reference_internal(dev, req, &rep_ext, file_priv);
1366 
1367 	if (unlikely(ret != 0))
1368 		return ret;
1369 
1370 	rep->creq = rep_ext.creq.base;
1371 	rep->crep = rep_ext.crep;
1372 
1373 	return ret;
1374 }
1375 
1376 /**
1377  * vmw_gb_surface_define_ext_ioctl - Ioctl function implementing
1378  * the user surface define functionality.
1379  *
1380  * @dev: Pointer to a struct drm_device.
1381  * @data: Pointer to data copied from / to user-space.
1382  * @file_priv: Pointer to a drm file private structure.
1383  */
1384 int vmw_gb_surface_define_ext_ioctl(struct drm_device *dev, void *data,
1385 				struct drm_file *file_priv)
1386 {
1387 	union drm_vmw_gb_surface_create_ext_arg *arg =
1388 	    (union drm_vmw_gb_surface_create_ext_arg *)data;
1389 	struct drm_vmw_gb_surface_create_ext_req *req = &arg->req;
1390 	struct drm_vmw_gb_surface_create_rep *rep = &arg->rep;
1391 
1392 	return vmw_gb_surface_define_internal(dev, req, rep, file_priv);
1393 }
1394 
1395 /**
1396  * vmw_gb_surface_reference_ext_ioctl - Ioctl function implementing
1397  * the user surface reference functionality.
1398  *
1399  * @dev: Pointer to a struct drm_device.
1400  * @data: Pointer to data copied from / to user-space.
1401  * @file_priv: Pointer to a drm file private structure.
1402  */
1403 int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev, void *data,
1404 				   struct drm_file *file_priv)
1405 {
1406 	union drm_vmw_gb_surface_reference_ext_arg *arg =
1407 	    (union drm_vmw_gb_surface_reference_ext_arg *)data;
1408 	struct drm_vmw_surface_arg *req = &arg->req;
1409 	struct drm_vmw_gb_surface_ref_ext_rep *rep = &arg->rep;
1410 
1411 	return vmw_gb_surface_reference_internal(dev, req, rep, file_priv);
1412 }
1413 
1414 /**
1415  * vmw_gb_surface_define_internal - Ioctl function implementing
1416  * the user surface define functionality.
1417  *
1418  * @dev: Pointer to a struct drm_device.
1419  * @req: Request argument from user-space.
1420  * @rep: Response argument to user-space.
1421  * @file_priv: Pointer to a drm file private structure.
1422  */
1423 static int
1424 vmw_gb_surface_define_internal(struct drm_device *dev,
1425 			       struct drm_vmw_gb_surface_create_ext_req *req,
1426 			       struct drm_vmw_gb_surface_create_rep *rep,
1427 			       struct drm_file *file_priv)
1428 {
1429 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1430 	struct vmw_private *dev_priv = vmw_priv(dev);
1431 	struct vmw_user_surface *user_srf;
1432 	struct vmw_surface_metadata metadata = {0};
1433 	struct vmw_surface *srf;
1434 	struct vmw_resource *res;
1435 	struct vmw_resource *tmp;
1436 	int ret = 0;
1437 	uint32_t backup_handle = 0;
1438 	SVGA3dSurfaceAllFlags svga3d_flags_64 =
1439 		SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits,
1440 				req->base.svga3d_flags);
1441 
1442 	/* array_size must be null for non-GL3 host. */
1443 	if (req->base.array_size > 0 && !has_sm4_context(dev_priv)) {
1444 		VMW_DEBUG_USER("SM4 surface not supported.\n");
1445 		return -EINVAL;
1446 	}
1447 
1448 	if (!has_sm4_1_context(dev_priv)) {
1449 		if (req->svga3d_flags_upper_32_bits != 0)
1450 			ret = -EINVAL;
1451 
1452 		if (req->base.multisample_count != 0)
1453 			ret = -EINVAL;
1454 
1455 		if (req->multisample_pattern != SVGA3D_MS_PATTERN_NONE)
1456 			ret = -EINVAL;
1457 
1458 		if (req->quality_level != SVGA3D_MS_QUALITY_NONE)
1459 			ret = -EINVAL;
1460 
1461 		if (ret) {
1462 			VMW_DEBUG_USER("SM4.1 surface not supported.\n");
1463 			return ret;
1464 		}
1465 	}
1466 
1467 	if (req->buffer_byte_stride > 0 && !has_sm5_context(dev_priv)) {
1468 		VMW_DEBUG_USER("SM5 surface not supported.\n");
1469 		return -EINVAL;
1470 	}
1471 
1472 	if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) &&
1473 	    req->base.multisample_count == 0) {
1474 		VMW_DEBUG_USER("Invalid sample count.\n");
1475 		return -EINVAL;
1476 	}
1477 
1478 	if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) {
1479 		VMW_DEBUG_USER("Invalid mip level.\n");
1480 		return -EINVAL;
1481 	}
1482 
1483 	metadata.flags = svga3d_flags_64;
1484 	metadata.format = req->base.format;
1485 	metadata.mip_levels[0] = req->base.mip_levels;
1486 	metadata.multisample_count = req->base.multisample_count;
1487 	metadata.multisample_pattern = req->multisample_pattern;
1488 	metadata.quality_level = req->quality_level;
1489 	metadata.array_size = req->base.array_size;
1490 	metadata.buffer_byte_stride = req->buffer_byte_stride;
1491 	metadata.num_sizes = 1;
1492 	metadata.base_size = req->base.base_size;
1493 	metadata.scanout = req->base.drm_surface_flags &
1494 		drm_vmw_surface_flag_scanout;
1495 
1496 	/* Define a surface based on the parameters. */
1497 	ret = vmw_gb_surface_define(dev_priv, &metadata, &srf);
1498 	if (ret != 0) {
1499 		VMW_DEBUG_USER("Failed to define surface.\n");
1500 		return ret;
1501 	}
1502 
1503 	user_srf = container_of(srf, struct vmw_user_surface, srf);
1504 	if (drm_is_primary_client(file_priv))
1505 		user_srf->master = drm_file_get_master(file_priv);
1506 
1507 	res = &user_srf->srf.res;
1508 
1509 	if (req->base.buffer_handle != SVGA3D_INVALID_ID) {
1510 		ret = vmw_user_bo_lookup(file_priv, req->base.buffer_handle,
1511 					 &res->guest_memory_bo);
1512 		if (ret == 0) {
1513 			if (res->guest_memory_bo->tbo.base.size < res->guest_memory_size) {
1514 				VMW_DEBUG_USER("Surface backup buffer too small.\n");
1515 				vmw_bo_unreference(&res->guest_memory_bo);
1516 				ret = -EINVAL;
1517 				goto out_unlock;
1518 			} else {
1519 				backup_handle = req->base.buffer_handle;
1520 			}
1521 		}
1522 	} else if (req->base.drm_surface_flags &
1523 		   (drm_vmw_surface_flag_create_buffer |
1524 		    drm_vmw_surface_flag_coherent)) {
1525 		ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
1526 							res->guest_memory_size,
1527 							&backup_handle,
1528 							&res->guest_memory_bo);
1529 		if (ret == 0)
1530 			vmw_bo_reference(res->guest_memory_bo);
1531 	}
1532 
1533 	if (unlikely(ret != 0)) {
1534 		vmw_resource_unreference(&res);
1535 		goto out_unlock;
1536 	}
1537 
1538 	if (req->base.drm_surface_flags & drm_vmw_surface_flag_coherent) {
1539 		struct vmw_bo *backup = res->guest_memory_bo;
1540 
1541 		ttm_bo_reserve(&backup->tbo, false, false, NULL);
1542 		if (!res->func->dirty_alloc)
1543 			ret = -EINVAL;
1544 		if (!ret)
1545 			ret = vmw_bo_dirty_add(backup);
1546 		if (!ret) {
1547 			res->coherent = true;
1548 			ret = res->func->dirty_alloc(res);
1549 		}
1550 		ttm_bo_unreserve(&backup->tbo);
1551 		if (ret) {
1552 			vmw_resource_unreference(&res);
1553 			goto out_unlock;
1554 		}
1555 
1556 	}
1557 
1558 	tmp = vmw_resource_reference(res);
1559 	ret = ttm_prime_object_init(tfile, res->guest_memory_size, &user_srf->prime,
1560 				    req->base.drm_surface_flags &
1561 				    drm_vmw_surface_flag_shareable,
1562 				    VMW_RES_SURFACE,
1563 				    &vmw_user_surface_base_release);
1564 
1565 	if (unlikely(ret != 0)) {
1566 		vmw_resource_unreference(&tmp);
1567 		vmw_resource_unreference(&res);
1568 		goto out_unlock;
1569 	}
1570 
1571 	rep->handle      = user_srf->prime.base.handle;
1572 	rep->backup_size = res->guest_memory_size;
1573 	if (res->guest_memory_bo) {
1574 		rep->buffer_map_handle =
1575 			drm_vma_node_offset_addr(&res->guest_memory_bo->tbo.base.vma_node);
1576 		rep->buffer_size = res->guest_memory_bo->tbo.base.size;
1577 		rep->buffer_handle = backup_handle;
1578 	} else {
1579 		rep->buffer_map_handle = 0;
1580 		rep->buffer_size = 0;
1581 		rep->buffer_handle = SVGA3D_INVALID_ID;
1582 	}
1583 	vmw_resource_unreference(&res);
1584 
1585 out_unlock:
1586 	return ret;
1587 }
1588 
1589 /**
1590  * vmw_gb_surface_reference_internal - Ioctl function implementing
1591  * the user surface reference functionality.
1592  *
1593  * @dev: Pointer to a struct drm_device.
1594  * @req: Pointer to user-space request surface arg.
1595  * @rep: Pointer to response to user-space.
1596  * @file_priv: Pointer to a drm file private structure.
1597  */
1598 static int
1599 vmw_gb_surface_reference_internal(struct drm_device *dev,
1600 				  struct drm_vmw_surface_arg *req,
1601 				  struct drm_vmw_gb_surface_ref_ext_rep *rep,
1602 				  struct drm_file *file_priv)
1603 {
1604 	struct vmw_private *dev_priv = vmw_priv(dev);
1605 	struct vmw_surface *srf;
1606 	struct vmw_user_surface *user_srf;
1607 	struct vmw_surface_metadata *metadata;
1608 	struct ttm_base_object *base;
1609 	u32 backup_handle;
1610 	int ret;
1611 
1612 	ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
1613 					   req->handle_type, &base);
1614 	if (unlikely(ret != 0))
1615 		return ret;
1616 
1617 	user_srf = container_of(base, struct vmw_user_surface, prime.base);
1618 	srf = &user_srf->srf;
1619 	if (!srf->res.guest_memory_bo) {
1620 		DRM_ERROR("Shared GB surface is missing a backup buffer.\n");
1621 		goto out_bad_resource;
1622 	}
1623 	metadata = &srf->metadata;
1624 
1625 	mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */
1626 	ret = drm_gem_handle_create(file_priv, &srf->res.guest_memory_bo->tbo.base,
1627 				    &backup_handle);
1628 	mutex_unlock(&dev_priv->cmdbuf_mutex);
1629 	if (ret != 0) {
1630 		drm_err(dev, "Wasn't able to create a backing handle for surface sid = %u.\n",
1631 			req->sid);
1632 		goto out_bad_resource;
1633 	}
1634 
1635 	rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(metadata->flags);
1636 	rep->creq.base.format = metadata->format;
1637 	rep->creq.base.mip_levels = metadata->mip_levels[0];
1638 	rep->creq.base.drm_surface_flags = 0;
1639 	rep->creq.base.multisample_count = metadata->multisample_count;
1640 	rep->creq.base.autogen_filter = metadata->autogen_filter;
1641 	rep->creq.base.array_size = metadata->array_size;
1642 	rep->creq.base.buffer_handle = backup_handle;
1643 	rep->creq.base.base_size = metadata->base_size;
1644 	rep->crep.handle = user_srf->prime.base.handle;
1645 	rep->crep.backup_size = srf->res.guest_memory_size;
1646 	rep->crep.buffer_handle = backup_handle;
1647 	rep->crep.buffer_map_handle =
1648 		drm_vma_node_offset_addr(&srf->res.guest_memory_bo->tbo.base.vma_node);
1649 	rep->crep.buffer_size = srf->res.guest_memory_bo->tbo.base.size;
1650 
1651 	rep->creq.version = drm_vmw_gb_surface_v1;
1652 	rep->creq.svga3d_flags_upper_32_bits =
1653 		SVGA3D_FLAGS_UPPER_32(metadata->flags);
1654 	rep->creq.multisample_pattern = metadata->multisample_pattern;
1655 	rep->creq.quality_level = metadata->quality_level;
1656 	rep->creq.must_be_zero = 0;
1657 
1658 out_bad_resource:
1659 	ttm_base_object_unref(&base);
1660 
1661 	return ret;
1662 }
1663 
1664 /**
1665  * vmw_subres_dirty_add - Add a dirty region to a subresource
1666  * @dirty: The surfaces's dirty tracker.
1667  * @loc_start: The location corresponding to the start of the region.
1668  * @loc_end: The location corresponding to the end of the region.
1669  *
1670  * As we are assuming that @loc_start and @loc_end represent a sequential
1671  * range of backing store memory, if the region spans multiple lines then
1672  * regardless of the x coordinate, the full lines are dirtied.
1673  * Correspondingly if the region spans multiple z slices, then full rather
1674  * than partial z slices are dirtied.
1675  */
1676 static void vmw_subres_dirty_add(struct vmw_surface_dirty *dirty,
1677 				 const struct vmw_surface_loc *loc_start,
1678 				 const struct vmw_surface_loc *loc_end)
1679 {
1680 	const struct vmw_surface_cache *cache = &dirty->cache;
1681 	SVGA3dBox *box = &dirty->boxes[loc_start->sub_resource];
1682 	u32 mip = loc_start->sub_resource % cache->num_mip_levels;
1683 	const struct drm_vmw_size *size = &cache->mip[mip].size;
1684 	u32 box_c2 = box->z + box->d;
1685 
1686 	if (WARN_ON(loc_start->sub_resource >= dirty->num_subres))
1687 		return;
1688 
1689 	if (box->d == 0 || box->z > loc_start->z)
1690 		box->z = loc_start->z;
1691 	if (box_c2 < loc_end->z)
1692 		box->d = loc_end->z - box->z;
1693 
1694 	if (loc_start->z + 1 == loc_end->z) {
1695 		box_c2 = box->y + box->h;
1696 		if (box->h == 0 || box->y > loc_start->y)
1697 			box->y = loc_start->y;
1698 		if (box_c2 < loc_end->y)
1699 			box->h = loc_end->y - box->y;
1700 
1701 		if (loc_start->y + 1 == loc_end->y) {
1702 			box_c2 = box->x + box->w;
1703 			if (box->w == 0 || box->x > loc_start->x)
1704 				box->x = loc_start->x;
1705 			if (box_c2 < loc_end->x)
1706 				box->w = loc_end->x - box->x;
1707 		} else {
1708 			box->x = 0;
1709 			box->w = size->width;
1710 		}
1711 	} else {
1712 		box->y = 0;
1713 		box->h = size->height;
1714 		box->x = 0;
1715 		box->w = size->width;
1716 	}
1717 }
1718 
1719 /**
1720  * vmw_subres_dirty_full - Mark a full subresource as dirty
1721  * @dirty: The surface's dirty tracker.
1722  * @subres: The subresource
1723  */
1724 static void vmw_subres_dirty_full(struct vmw_surface_dirty *dirty, u32 subres)
1725 {
1726 	const struct vmw_surface_cache *cache = &dirty->cache;
1727 	u32 mip = subres % cache->num_mip_levels;
1728 	const struct drm_vmw_size *size = &cache->mip[mip].size;
1729 	SVGA3dBox *box = &dirty->boxes[subres];
1730 
1731 	box->x = 0;
1732 	box->y = 0;
1733 	box->z = 0;
1734 	box->w = size->width;
1735 	box->h = size->height;
1736 	box->d = size->depth;
1737 }
1738 
1739 /*
1740  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for texture
1741  * surfaces.
1742  */
1743 static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res,
1744 					    size_t start, size_t end)
1745 {
1746 	struct vmw_surface_dirty *dirty =
1747 		(struct vmw_surface_dirty *) res->dirty;
1748 	size_t backup_end = res->guest_memory_offset + res->guest_memory_size;
1749 	struct vmw_surface_loc loc1, loc2;
1750 	const struct vmw_surface_cache *cache;
1751 
1752 	start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1753 	end = min(end, backup_end) - res->guest_memory_offset;
1754 	cache = &dirty->cache;
1755 	vmw_surface_get_loc(cache, &loc1, start);
1756 	vmw_surface_get_loc(cache, &loc2, end - 1);
1757 	vmw_surface_inc_loc(cache, &loc2);
1758 
1759 	if (loc1.sheet != loc2.sheet) {
1760 		u32 sub_res;
1761 
1762 		/*
1763 		 * Multiple multisample sheets. To do this in an optimized
1764 		 * fashion, compute the dirty region for each sheet and the
1765 		 * resulting union. Since this is not a common case, just dirty
1766 		 * the whole surface.
1767 		 */
1768 		for (sub_res = 0; sub_res < dirty->num_subres; ++sub_res)
1769 			vmw_subres_dirty_full(dirty, sub_res);
1770 		return;
1771 	}
1772 	if (loc1.sub_resource + 1 == loc2.sub_resource) {
1773 		/* Dirty range covers a single sub-resource */
1774 		vmw_subres_dirty_add(dirty, &loc1, &loc2);
1775 	} else {
1776 		/* Dirty range covers multiple sub-resources */
1777 		struct vmw_surface_loc loc_min, loc_max;
1778 		u32 sub_res;
1779 
1780 		vmw_surface_max_loc(cache, loc1.sub_resource, &loc_max);
1781 		vmw_subres_dirty_add(dirty, &loc1, &loc_max);
1782 		vmw_surface_min_loc(cache, loc2.sub_resource - 1, &loc_min);
1783 		vmw_subres_dirty_add(dirty, &loc_min, &loc2);
1784 		for (sub_res = loc1.sub_resource + 1;
1785 		     sub_res < loc2.sub_resource - 1; ++sub_res)
1786 			vmw_subres_dirty_full(dirty, sub_res);
1787 	}
1788 }
1789 
1790 /*
1791  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for buffer
1792  * surfaces.
1793  */
1794 static void vmw_surface_buf_dirty_range_add(struct vmw_resource *res,
1795 					    size_t start, size_t end)
1796 {
1797 	struct vmw_surface_dirty *dirty =
1798 		(struct vmw_surface_dirty *) res->dirty;
1799 	const struct vmw_surface_cache *cache = &dirty->cache;
1800 	size_t backup_end = res->guest_memory_offset + cache->mip_chain_bytes;
1801 	SVGA3dBox *box = &dirty->boxes[0];
1802 	u32 box_c2;
1803 
1804 	box->h = box->d = 1;
1805 	start = max_t(size_t, start, res->guest_memory_offset) - res->guest_memory_offset;
1806 	end = min(end, backup_end) - res->guest_memory_offset;
1807 	box_c2 = box->x + box->w;
1808 	if (box->w == 0 || box->x > start)
1809 		box->x = start;
1810 	if (box_c2 < end)
1811 		box->w = end - box->x;
1812 }
1813 
1814 /*
1815  * vmw_surface_tex_dirty_add_range - The dirty_add_range callback for surfaces
1816  */
1817 static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start,
1818 					size_t end)
1819 {
1820 	struct vmw_surface *srf = vmw_res_to_srf(res);
1821 
1822 	if (WARN_ON(end <= res->guest_memory_offset ||
1823 		    start >= res->guest_memory_offset + res->guest_memory_size))
1824 		return;
1825 
1826 	if (srf->metadata.format == SVGA3D_BUFFER)
1827 		vmw_surface_buf_dirty_range_add(res, start, end);
1828 	else
1829 		vmw_surface_tex_dirty_range_add(res, start, end);
1830 }
1831 
1832 /*
1833  * vmw_surface_dirty_sync - The surface's dirty_sync callback.
1834  */
1835 static int vmw_surface_dirty_sync(struct vmw_resource *res)
1836 {
1837 	struct vmw_private *dev_priv = res->dev_priv;
1838 	u32 i, num_dirty;
1839 	struct vmw_surface_dirty *dirty =
1840 		(struct vmw_surface_dirty *) res->dirty;
1841 	size_t alloc_size;
1842 	const struct vmw_surface_cache *cache = &dirty->cache;
1843 	struct {
1844 		SVGA3dCmdHeader header;
1845 		SVGA3dCmdDXUpdateSubResource body;
1846 	} *cmd1;
1847 	struct {
1848 		SVGA3dCmdHeader header;
1849 		SVGA3dCmdUpdateGBImage body;
1850 	} *cmd2;
1851 	void *cmd;
1852 
1853 	num_dirty = 0;
1854 	for (i = 0; i < dirty->num_subres; ++i) {
1855 		const SVGA3dBox *box = &dirty->boxes[i];
1856 
1857 		if (box->d)
1858 			num_dirty++;
1859 	}
1860 
1861 	if (!num_dirty)
1862 		goto out;
1863 
1864 	alloc_size = num_dirty * ((has_sm4_context(dev_priv)) ? sizeof(*cmd1) : sizeof(*cmd2));
1865 	cmd = VMW_CMD_RESERVE(dev_priv, alloc_size);
1866 	if (!cmd)
1867 		return -ENOMEM;
1868 
1869 	cmd1 = cmd;
1870 	cmd2 = cmd;
1871 
1872 	for (i = 0; i < dirty->num_subres; ++i) {
1873 		const SVGA3dBox *box = &dirty->boxes[i];
1874 
1875 		if (!box->d)
1876 			continue;
1877 
1878 		/*
1879 		 * DX_UPDATE_SUBRESOURCE is aware of array surfaces.
1880 		 * UPDATE_GB_IMAGE is not.
1881 		 */
1882 		if (has_sm4_context(dev_priv)) {
1883 			cmd1->header.id = SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE;
1884 			cmd1->header.size = sizeof(cmd1->body);
1885 			cmd1->body.sid = res->id;
1886 			cmd1->body.subResource = i;
1887 			cmd1->body.box = *box;
1888 			cmd1++;
1889 		} else {
1890 			cmd2->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
1891 			cmd2->header.size = sizeof(cmd2->body);
1892 			cmd2->body.image.sid = res->id;
1893 			cmd2->body.image.face = i / cache->num_mip_levels;
1894 			cmd2->body.image.mipmap = i -
1895 				(cache->num_mip_levels * cmd2->body.image.face);
1896 			cmd2->body.box = *box;
1897 			cmd2++;
1898 		}
1899 
1900 	}
1901 	vmw_cmd_commit(dev_priv, alloc_size);
1902  out:
1903 	memset(&dirty->boxes[0], 0, sizeof(dirty->boxes[0]) *
1904 	       dirty->num_subres);
1905 
1906 	return 0;
1907 }
1908 
1909 /*
1910  * vmw_surface_dirty_alloc - The surface's dirty_alloc callback.
1911  */
1912 static int vmw_surface_dirty_alloc(struct vmw_resource *res)
1913 {
1914 	struct vmw_surface *srf = vmw_res_to_srf(res);
1915 	const struct vmw_surface_metadata *metadata = &srf->metadata;
1916 	struct vmw_surface_dirty *dirty;
1917 	u32 num_layers = 1;
1918 	u32 num_mip;
1919 	u32 num_subres;
1920 	u32 num_samples;
1921 	size_t dirty_size;
1922 	int ret;
1923 
1924 	if (metadata->array_size)
1925 		num_layers = metadata->array_size;
1926 	else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP)
1927 		num_layers *= SVGA3D_MAX_SURFACE_FACES;
1928 
1929 	num_mip = metadata->mip_levels[0];
1930 	if (!num_mip)
1931 		num_mip = 1;
1932 
1933 	num_subres = num_layers * num_mip;
1934 	dirty_size = struct_size(dirty, boxes, num_subres);
1935 
1936 	dirty = kvzalloc(dirty_size, GFP_KERNEL);
1937 	if (!dirty) {
1938 		ret = -ENOMEM;
1939 		goto out_no_dirty;
1940 	}
1941 
1942 	num_samples = max_t(u32, 1, metadata->multisample_count);
1943 	ret = vmw_surface_setup_cache(&metadata->base_size, metadata->format,
1944 				      num_mip, num_layers, num_samples,
1945 				      &dirty->cache);
1946 	if (ret)
1947 		goto out_no_cache;
1948 
1949 	dirty->num_subres = num_subres;
1950 	res->dirty = (struct vmw_resource_dirty *) dirty;
1951 
1952 	return 0;
1953 
1954 out_no_cache:
1955 	kvfree(dirty);
1956 out_no_dirty:
1957 	return ret;
1958 }
1959 
1960 /*
1961  * vmw_surface_dirty_free - The surface's dirty_free callback
1962  */
1963 static void vmw_surface_dirty_free(struct vmw_resource *res)
1964 {
1965 	struct vmw_surface_dirty *dirty =
1966 		(struct vmw_surface_dirty *) res->dirty;
1967 
1968 	kvfree(dirty);
1969 	res->dirty = NULL;
1970 }
1971 
1972 /*
1973  * vmw_surface_clean - The surface's clean callback
1974  */
1975 static int vmw_surface_clean(struct vmw_resource *res)
1976 {
1977 	struct vmw_private *dev_priv = res->dev_priv;
1978 	size_t alloc_size;
1979 	struct {
1980 		SVGA3dCmdHeader header;
1981 		SVGA3dCmdReadbackGBSurface body;
1982 	} *cmd;
1983 
1984 	alloc_size = sizeof(*cmd);
1985 	cmd = VMW_CMD_RESERVE(dev_priv, alloc_size);
1986 	if (!cmd)
1987 		return -ENOMEM;
1988 
1989 	cmd->header.id = SVGA_3D_CMD_READBACK_GB_SURFACE;
1990 	cmd->header.size = sizeof(cmd->body);
1991 	cmd->body.sid = res->id;
1992 	vmw_cmd_commit(dev_priv, alloc_size);
1993 
1994 	return 0;
1995 }
1996 
1997 /*
1998  * vmw_gb_surface_define - Define a private GB surface
1999  *
2000  * @dev_priv: Pointer to a device private.
2001  * @metadata: Metadata representing the surface to create.
2002  * @user_srf_out: allocated user_srf. Set to NULL on failure.
2003  *
2004  * GB surfaces allocated by this function will not have a user mode handle, and
2005  * thus will only be visible to vmwgfx.  For optimization reasons the
2006  * surface may later be given a user mode handle by another function to make
2007  * it available to user mode drivers.
2008  */
2009 int vmw_gb_surface_define(struct vmw_private *dev_priv,
2010 			  const struct vmw_surface_metadata *req,
2011 			  struct vmw_surface **srf_out)
2012 {
2013 	struct vmw_surface_metadata *metadata;
2014 	struct vmw_user_surface *user_srf;
2015 	struct vmw_surface *srf;
2016 	u32 sample_count = 1;
2017 	u32 num_layers = 1;
2018 	int ret;
2019 
2020 	*srf_out = NULL;
2021 
2022 	if (req->scanout) {
2023 		if (!vmw_surface_is_screen_target_format(req->format)) {
2024 			VMW_DEBUG_USER("Invalid Screen Target surface format.");
2025 			return -EINVAL;
2026 		}
2027 
2028 		if (req->base_size.width > dev_priv->texture_max_width ||
2029 		    req->base_size.height > dev_priv->texture_max_height) {
2030 			VMW_DEBUG_USER("%ux%u\n, exceed max surface size %ux%u",
2031 				       req->base_size.width,
2032 				       req->base_size.height,
2033 				       dev_priv->texture_max_width,
2034 				       dev_priv->texture_max_height);
2035 			return -EINVAL;
2036 		}
2037 	} else {
2038 		const SVGA3dSurfaceDesc *desc =
2039 			vmw_surface_get_desc(req->format);
2040 
2041 		if (desc->blockDesc == SVGA3DBLOCKDESC_NONE) {
2042 			VMW_DEBUG_USER("Invalid surface format.\n");
2043 			return -EINVAL;
2044 		}
2045 	}
2046 
2047 	if (req->autogen_filter != SVGA3D_TEX_FILTER_NONE)
2048 		return -EINVAL;
2049 
2050 	if (req->num_sizes != 1)
2051 		return -EINVAL;
2052 
2053 	if (req->sizes != NULL)
2054 		return -EINVAL;
2055 
2056 	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
2057 	if (unlikely(!user_srf)) {
2058 		ret = -ENOMEM;
2059 		goto out_unlock;
2060 	}
2061 
2062 	*srf_out  = &user_srf->srf;
2063 	user_srf->prime.base.shareable = false;
2064 	user_srf->prime.base.tfile = NULL;
2065 
2066 	srf = &user_srf->srf;
2067 	srf->metadata = *req;
2068 	srf->offsets = NULL;
2069 
2070 	metadata = &srf->metadata;
2071 
2072 	if (metadata->array_size)
2073 		num_layers = req->array_size;
2074 	else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP)
2075 		num_layers = SVGA3D_MAX_SURFACE_FACES;
2076 
2077 	if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE)
2078 		sample_count = metadata->multisample_count;
2079 
2080 	srf->res.guest_memory_size =
2081 		vmw_surface_get_serialized_size_extended(
2082 				metadata->format,
2083 				metadata->base_size,
2084 				metadata->mip_levels[0],
2085 				num_layers,
2086 				sample_count);
2087 
2088 	if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT)
2089 		srf->res.guest_memory_size += sizeof(SVGA3dDXSOState);
2090 
2091 	/*
2092 	 * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with
2093 	 * size greater than STDU max width/height. This is really a workaround
2094 	 * to support creation of big framebuffer requested by some user-space
2095 	 * for whole topology. That big framebuffer won't really be used for
2096 	 * binding with screen target as during prepare_fb a separate surface is
2097 	 * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag.
2098 	 */
2099 	if (dev_priv->active_display_unit == vmw_du_screen_target &&
2100 	    metadata->scanout &&
2101 	    metadata->base_size.width <= dev_priv->stdu_max_width &&
2102 	    metadata->base_size.height <= dev_priv->stdu_max_height)
2103 		metadata->flags |= SVGA3D_SURFACE_SCREENTARGET;
2104 
2105 	/*
2106 	 * From this point, the generic resource management functions
2107 	 * destroy the object on failure.
2108 	 */
2109 	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
2110 
2111 	return ret;
2112 
2113 out_unlock:
2114 	return ret;
2115 }
2116