1 /**************************************************************************
2  *
3  * Copyright © 2009-2012 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 "vmwgfx_drv.h"
29 #include "vmwgfx_resource_priv.h"
30 #include <ttm/ttm_placement.h>
31 #include "svga3d_surfacedefs.h"
32 
33 /**
34  * struct vmw_user_surface - User-space visible surface resource
35  *
36  * @base:           The TTM base object handling user-space visibility.
37  * @srf:            The surface metadata.
38  * @size:           TTM accounting size for the surface.
39  */
40 struct vmw_user_surface {
41 	struct ttm_prime_object prime;
42 	struct vmw_surface srf;
43 	uint32_t size;
44 	uint32_t backup_handle;
45 };
46 
47 /**
48  * struct vmw_surface_offset - Backing store mip level offset info
49  *
50  * @face:           Surface face.
51  * @mip:            Mip level.
52  * @bo_offset:      Offset into backing store of this mip level.
53  *
54  */
55 struct vmw_surface_offset {
56 	uint32_t face;
57 	uint32_t mip;
58 	uint32_t bo_offset;
59 };
60 
61 static void vmw_user_surface_free(struct vmw_resource *res);
62 static struct vmw_resource *
63 vmw_user_surface_base_to_res(struct ttm_base_object *base);
64 static int vmw_legacy_srf_bind(struct vmw_resource *res,
65 			       struct ttm_validate_buffer *val_buf);
66 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
67 				 bool readback,
68 				 struct ttm_validate_buffer *val_buf);
69 static int vmw_legacy_srf_create(struct vmw_resource *res);
70 static int vmw_legacy_srf_destroy(struct vmw_resource *res);
71 
72 static const struct vmw_user_resource_conv user_surface_conv = {
73 	.object_type = VMW_RES_SURFACE,
74 	.base_obj_to_res = vmw_user_surface_base_to_res,
75 	.res_free = vmw_user_surface_free
76 };
77 
78 const struct vmw_user_resource_conv *user_surface_converter =
79 	&user_surface_conv;
80 
81 
82 static uint64_t vmw_user_surface_size;
83 
84 static const struct vmw_res_func vmw_legacy_surface_func = {
85 	.res_type = vmw_res_surface,
86 	.needs_backup = false,
87 	.may_evict = true,
88 	.type_name = "legacy surfaces",
89 	.backup_placement = &vmw_srf_placement,
90 	.create = &vmw_legacy_srf_create,
91 	.destroy = &vmw_legacy_srf_destroy,
92 	.bind = &vmw_legacy_srf_bind,
93 	.unbind = &vmw_legacy_srf_unbind
94 };
95 
96 /**
97  * struct vmw_surface_dma - SVGA3D DMA command
98  */
99 struct vmw_surface_dma {
100 	SVGA3dCmdHeader header;
101 	SVGA3dCmdSurfaceDMA body;
102 	SVGA3dCopyBox cb;
103 	SVGA3dCmdSurfaceDMASuffix suffix;
104 };
105 
106 /**
107  * struct vmw_surface_define - SVGA3D Surface Define command
108  */
109 struct vmw_surface_define {
110 	SVGA3dCmdHeader header;
111 	SVGA3dCmdDefineSurface body;
112 };
113 
114 /**
115  * struct vmw_surface_destroy - SVGA3D Surface Destroy command
116  */
117 struct vmw_surface_destroy {
118 	SVGA3dCmdHeader header;
119 	SVGA3dCmdDestroySurface body;
120 };
121 
122 
123 /**
124  * vmw_surface_dma_size - Compute fifo size for a dma command.
125  *
126  * @srf: Pointer to a struct vmw_surface
127  *
128  * Computes the required size for a surface dma command for backup or
129  * restoration of the surface represented by @srf.
130  */
131 static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf)
132 {
133 	return srf->num_sizes * sizeof(struct vmw_surface_dma);
134 }
135 
136 
137 /**
138  * vmw_surface_define_size - Compute fifo size for a surface define command.
139  *
140  * @srf: Pointer to a struct vmw_surface
141  *
142  * Computes the required size for a surface define command for the definition
143  * of the surface represented by @srf.
144  */
145 static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf)
146 {
147 	return sizeof(struct vmw_surface_define) + srf->num_sizes *
148 		sizeof(SVGA3dSize);
149 }
150 
151 
152 /**
153  * vmw_surface_destroy_size - Compute fifo size for a surface destroy command.
154  *
155  * Computes the required size for a surface destroy command for the destruction
156  * of a hw surface.
157  */
158 static inline uint32_t vmw_surface_destroy_size(void)
159 {
160 	return sizeof(struct vmw_surface_destroy);
161 }
162 
163 /**
164  * vmw_surface_destroy_encode - Encode a surface_destroy command.
165  *
166  * @id: The surface id
167  * @cmd_space: Pointer to memory area in which the commands should be encoded.
168  */
169 static void vmw_surface_destroy_encode(uint32_t id,
170 				       void *cmd_space)
171 {
172 	struct vmw_surface_destroy *cmd = (struct vmw_surface_destroy *)
173 		cmd_space;
174 
175 	cmd->header.id = SVGA_3D_CMD_SURFACE_DESTROY;
176 	cmd->header.size = sizeof(cmd->body);
177 	cmd->body.sid = id;
178 }
179 
180 /**
181  * vmw_surface_define_encode - Encode a surface_define command.
182  *
183  * @srf: Pointer to a struct vmw_surface object.
184  * @cmd_space: Pointer to memory area in which the commands should be encoded.
185  */
186 static void vmw_surface_define_encode(const struct vmw_surface *srf,
187 				      void *cmd_space)
188 {
189 	struct vmw_surface_define *cmd = (struct vmw_surface_define *)
190 		cmd_space;
191 	struct drm_vmw_size *src_size;
192 	SVGA3dSize *cmd_size;
193 	uint32_t cmd_len;
194 	int i;
195 
196 	cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize);
197 
198 	cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE;
199 	cmd->header.size = cmd_len;
200 	cmd->body.sid = srf->res.id;
201 	cmd->body.surfaceFlags = srf->flags;
202 	cmd->body.format = cpu_to_le32(srf->format);
203 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
204 		cmd->body.face[i].numMipLevels = srf->mip_levels[i];
205 
206 	cmd += 1;
207 	cmd_size = (SVGA3dSize *) cmd;
208 	src_size = srf->sizes;
209 
210 	for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) {
211 		cmd_size->width = src_size->width;
212 		cmd_size->height = src_size->height;
213 		cmd_size->depth = src_size->depth;
214 	}
215 }
216 
217 /**
218  * vmw_surface_dma_encode - Encode a surface_dma command.
219  *
220  * @srf: Pointer to a struct vmw_surface object.
221  * @cmd_space: Pointer to memory area in which the commands should be encoded.
222  * @ptr: Pointer to an SVGAGuestPtr indicating where the surface contents
223  * should be placed or read from.
224  * @to_surface: Boolean whether to DMA to the surface or from the surface.
225  */
226 static void vmw_surface_dma_encode(struct vmw_surface *srf,
227 				   void *cmd_space,
228 				   const SVGAGuestPtr *ptr,
229 				   bool to_surface)
230 {
231 	uint32_t i;
232 	struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space;
233 	const struct svga3d_surface_desc *desc =
234 		svga3dsurface_get_desc(srf->format);
235 
236 	for (i = 0; i < srf->num_sizes; ++i) {
237 		SVGA3dCmdHeader *header = &cmd->header;
238 		SVGA3dCmdSurfaceDMA *body = &cmd->body;
239 		SVGA3dCopyBox *cb = &cmd->cb;
240 		SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix;
241 		const struct vmw_surface_offset *cur_offset = &srf->offsets[i];
242 		const struct drm_vmw_size *cur_size = &srf->sizes[i];
243 
244 		header->id = SVGA_3D_CMD_SURFACE_DMA;
245 		header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix);
246 
247 		body->guest.ptr = *ptr;
248 		body->guest.ptr.offset += cur_offset->bo_offset;
249 		body->guest.pitch = svga3dsurface_calculate_pitch(desc,
250 								  cur_size);
251 		body->host.sid = srf->res.id;
252 		body->host.face = cur_offset->face;
253 		body->host.mipmap = cur_offset->mip;
254 		body->transfer = ((to_surface) ?  SVGA3D_WRITE_HOST_VRAM :
255 				  SVGA3D_READ_HOST_VRAM);
256 		cb->x = 0;
257 		cb->y = 0;
258 		cb->z = 0;
259 		cb->srcx = 0;
260 		cb->srcy = 0;
261 		cb->srcz = 0;
262 		cb->w = cur_size->width;
263 		cb->h = cur_size->height;
264 		cb->d = cur_size->depth;
265 
266 		suffix->suffixSize = sizeof(*suffix);
267 		suffix->maximumOffset =
268 			svga3dsurface_get_image_buffer_size(desc, cur_size,
269 							    body->guest.pitch);
270 		suffix->flags.discard = 0;
271 		suffix->flags.unsynchronized = 0;
272 		suffix->flags.reserved = 0;
273 		++cmd;
274 	}
275 };
276 
277 
278 /**
279  * vmw_hw_surface_destroy - destroy a Device surface
280  *
281  * @res:        Pointer to a struct vmw_resource embedded in a struct
282  *              vmw_surface.
283  *
284  * Destroys a the device surface associated with a struct vmw_surface if
285  * any, and adjusts accounting and resource count accordingly.
286  */
287 static void vmw_hw_surface_destroy(struct vmw_resource *res)
288 {
289 
290 	struct vmw_private *dev_priv = res->dev_priv;
291 	struct vmw_surface *srf;
292 	void *cmd;
293 
294 	if (res->id != -1) {
295 
296 		cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size());
297 		if (unlikely(cmd == NULL)) {
298 			DRM_ERROR("Failed reserving FIFO space for surface "
299 				  "destruction.\n");
300 			return;
301 		}
302 
303 		vmw_surface_destroy_encode(res->id, cmd);
304 		vmw_fifo_commit(dev_priv, vmw_surface_destroy_size());
305 
306 		/*
307 		 * used_memory_size_atomic, or separate lock
308 		 * to avoid taking dev_priv::cmdbuf_mutex in
309 		 * the destroy path.
310 		 */
311 
312 		mutex_lock(&dev_priv->cmdbuf_mutex);
313 		srf = vmw_res_to_srf(res);
314 		dev_priv->used_memory_size -= res->backup_size;
315 		mutex_unlock(&dev_priv->cmdbuf_mutex);
316 	}
317 	vmw_3d_resource_dec(dev_priv, false);
318 }
319 
320 /**
321  * vmw_legacy_srf_create - Create a device surface as part of the
322  * resource validation process.
323  *
324  * @res: Pointer to a struct vmw_surface.
325  *
326  * If the surface doesn't have a hw id.
327  *
328  * Returns -EBUSY if there wasn't sufficient device resources to
329  * complete the validation. Retry after freeing up resources.
330  *
331  * May return other errors if the kernel is out of guest resources.
332  */
333 static int vmw_legacy_srf_create(struct vmw_resource *res)
334 {
335 	struct vmw_private *dev_priv = res->dev_priv;
336 	struct vmw_surface *srf;
337 	uint32_t submit_size;
338 	uint8_t *cmd;
339 	int ret;
340 
341 	if (likely(res->id != -1))
342 		return 0;
343 
344 	srf = vmw_res_to_srf(res);
345 	if (unlikely(dev_priv->used_memory_size + res->backup_size >=
346 		     dev_priv->memory_size))
347 		return -EBUSY;
348 
349 	/*
350 	 * Alloc id for the resource.
351 	 */
352 
353 	ret = vmw_resource_alloc_id(res);
354 	if (unlikely(ret != 0)) {
355 		DRM_ERROR("Failed to allocate a surface id.\n");
356 		goto out_no_id;
357 	}
358 
359 	if (unlikely(res->id >= SVGA3D_MAX_SURFACE_IDS)) {
360 		ret = -EBUSY;
361 		goto out_no_fifo;
362 	}
363 
364 	/*
365 	 * Encode surface define- commands.
366 	 */
367 
368 	submit_size = vmw_surface_define_size(srf);
369 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
370 	if (unlikely(cmd == NULL)) {
371 		DRM_ERROR("Failed reserving FIFO space for surface "
372 			  "creation.\n");
373 		ret = -ENOMEM;
374 		goto out_no_fifo;
375 	}
376 
377 	vmw_surface_define_encode(srf, cmd);
378 	vmw_fifo_commit(dev_priv, submit_size);
379 	/*
380 	 * Surface memory usage accounting.
381 	 */
382 
383 	dev_priv->used_memory_size += res->backup_size;
384 	return 0;
385 
386 out_no_fifo:
387 	vmw_resource_release_id(res);
388 out_no_id:
389 	return ret;
390 }
391 
392 /**
393  * vmw_legacy_srf_dma - Copy backup data to or from a legacy surface.
394  *
395  * @res:            Pointer to a struct vmw_res embedded in a struct
396  *                  vmw_surface.
397  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
398  *                  information about the backup buffer.
399  * @bind:           Boolean wether to DMA to the surface.
400  *
401  * Transfer backup data to or from a legacy surface as part of the
402  * validation process.
403  * May return other errors if the kernel is out of guest resources.
404  * The backup buffer will be fenced or idle upon successful completion,
405  * and if the surface needs persistent backup storage, the backup buffer
406  * will also be returned reserved iff @bind is true.
407  */
408 static int vmw_legacy_srf_dma(struct vmw_resource *res,
409 			      struct ttm_validate_buffer *val_buf,
410 			      bool bind)
411 {
412 	SVGAGuestPtr ptr;
413 	struct vmw_fence_obj *fence;
414 	uint32_t submit_size;
415 	struct vmw_surface *srf = vmw_res_to_srf(res);
416 	uint8_t *cmd;
417 	struct vmw_private *dev_priv = res->dev_priv;
418 
419 	BUG_ON(val_buf->bo == NULL);
420 
421 	submit_size = vmw_surface_dma_size(srf);
422 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
423 	if (unlikely(cmd == NULL)) {
424 		DRM_ERROR("Failed reserving FIFO space for surface "
425 			  "DMA.\n");
426 		return -ENOMEM;
427 	}
428 	vmw_bo_get_guest_ptr(val_buf->bo, &ptr);
429 	vmw_surface_dma_encode(srf, cmd, &ptr, bind);
430 
431 	vmw_fifo_commit(dev_priv, submit_size);
432 
433 	/*
434 	 * Create a fence object and fence the backup buffer.
435 	 */
436 
437 	(void) vmw_execbuf_fence_commands(NULL, dev_priv,
438 					  &fence, NULL);
439 
440 	vmw_fence_single_bo(val_buf->bo, fence);
441 
442 	if (likely(fence != NULL))
443 		vmw_fence_obj_unreference(&fence);
444 
445 	return 0;
446 }
447 
448 /**
449  * vmw_legacy_srf_bind - Perform a legacy surface bind as part of the
450  *                       surface validation process.
451  *
452  * @res:            Pointer to a struct vmw_res embedded in a struct
453  *                  vmw_surface.
454  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
455  *                  information about the backup buffer.
456  *
457  * This function will copy backup data to the surface if the
458  * backup buffer is dirty.
459  */
460 static int vmw_legacy_srf_bind(struct vmw_resource *res,
461 			       struct ttm_validate_buffer *val_buf)
462 {
463 	if (!res->backup_dirty)
464 		return 0;
465 
466 	return vmw_legacy_srf_dma(res, val_buf, true);
467 }
468 
469 
470 /**
471  * vmw_legacy_srf_unbind - Perform a legacy surface unbind as part of the
472  *                         surface eviction process.
473  *
474  * @res:            Pointer to a struct vmw_res embedded in a struct
475  *                  vmw_surface.
476  * @val_buf:        Pointer to a struct ttm_validate_buffer containing
477  *                  information about the backup buffer.
478  *
479  * This function will copy backup data from the surface.
480  */
481 static int vmw_legacy_srf_unbind(struct vmw_resource *res,
482 				 bool readback,
483 				 struct ttm_validate_buffer *val_buf)
484 {
485 	if (unlikely(readback))
486 		return vmw_legacy_srf_dma(res, val_buf, false);
487 	return 0;
488 }
489 
490 /**
491  * vmw_legacy_srf_destroy - Destroy a device surface as part of a
492  *                          resource eviction process.
493  *
494  * @res:            Pointer to a struct vmw_res embedded in a struct
495  *                  vmw_surface.
496  */
497 static int vmw_legacy_srf_destroy(struct vmw_resource *res)
498 {
499 	struct vmw_private *dev_priv = res->dev_priv;
500 	uint32_t submit_size;
501 	uint8_t *cmd;
502 
503 	BUG_ON(res->id == -1);
504 
505 	/*
506 	 * Encode the dma- and surface destroy commands.
507 	 */
508 
509 	submit_size = vmw_surface_destroy_size();
510 	cmd = vmw_fifo_reserve(dev_priv, submit_size);
511 	if (unlikely(cmd == NULL)) {
512 		DRM_ERROR("Failed reserving FIFO space for surface "
513 			  "eviction.\n");
514 		return -ENOMEM;
515 	}
516 
517 	vmw_surface_destroy_encode(res->id, cmd);
518 	vmw_fifo_commit(dev_priv, submit_size);
519 
520 	/*
521 	 * Surface memory usage accounting.
522 	 */
523 
524 	dev_priv->used_memory_size -= res->backup_size;
525 
526 	/*
527 	 * Release the surface ID.
528 	 */
529 
530 	vmw_resource_release_id(res);
531 
532 	return 0;
533 }
534 
535 
536 /**
537  * vmw_surface_init - initialize a struct vmw_surface
538  *
539  * @dev_priv:       Pointer to a device private struct.
540  * @srf:            Pointer to the struct vmw_surface to initialize.
541  * @res_free:       Pointer to a resource destructor used to free
542  *                  the object.
543  */
544 static int vmw_surface_init(struct vmw_private *dev_priv,
545 			    struct vmw_surface *srf,
546 			    void (*res_free) (struct vmw_resource *res))
547 {
548 	int ret;
549 	struct vmw_resource *res = &srf->res;
550 
551 	BUG_ON(res_free == NULL);
552 	(void) vmw_3d_resource_inc(dev_priv, false);
553 	ret = vmw_resource_init(dev_priv, res, true, res_free,
554 				&vmw_legacy_surface_func);
555 
556 	if (unlikely(ret != 0)) {
557 		vmw_3d_resource_dec(dev_priv, false);
558 		res_free(res);
559 		return ret;
560 	}
561 
562 	/*
563 	 * The surface won't be visible to hardware until a
564 	 * surface validate.
565 	 */
566 
567 	vmw_resource_activate(res, vmw_hw_surface_destroy);
568 	return ret;
569 }
570 
571 /**
572  * vmw_user_surface_base_to_res - TTM base object to resource converter for
573  *                                user visible surfaces
574  *
575  * @base:           Pointer to a TTM base object
576  *
577  * Returns the struct vmw_resource embedded in a struct vmw_surface
578  * for the user-visible object identified by the TTM base object @base.
579  */
580 static struct vmw_resource *
581 vmw_user_surface_base_to_res(struct ttm_base_object *base)
582 {
583 	return &(container_of(base, struct vmw_user_surface,
584 			      prime.base)->srf.res);
585 }
586 
587 /**
588  * vmw_user_surface_free - User visible surface resource destructor
589  *
590  * @res:            A struct vmw_resource embedded in a struct vmw_surface.
591  */
592 static void vmw_user_surface_free(struct vmw_resource *res)
593 {
594 	struct vmw_surface *srf = vmw_res_to_srf(res);
595 	struct vmw_user_surface *user_srf =
596 	    container_of(srf, struct vmw_user_surface, srf);
597 	struct vmw_private *dev_priv = srf->res.dev_priv;
598 	uint32_t size = user_srf->size;
599 
600 	kfree(srf->offsets);
601 	kfree(srf->sizes);
602 	kfree(srf->snooper.image);
603 	ttm_prime_object_kfree(user_srf, prime);
604 	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
605 }
606 
607 /**
608  * vmw_user_surface_free - User visible surface TTM base object destructor
609  *
610  * @p_base:         Pointer to a pointer to a TTM base object
611  *                  embedded in a struct vmw_user_surface.
612  *
613  * Drops the base object's reference on its resource, and the
614  * pointer pointed to by *p_base is set to NULL.
615  */
616 static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
617 {
618 	struct ttm_base_object *base = *p_base;
619 	struct vmw_user_surface *user_srf =
620 	    container_of(base, struct vmw_user_surface, prime.base);
621 	struct vmw_resource *res = &user_srf->srf.res;
622 
623 	*p_base = NULL;
624 	vmw_resource_unreference(&res);
625 }
626 
627 /**
628  * vmw_user_surface_destroy_ioctl - Ioctl function implementing
629  *                                  the user surface destroy functionality.
630  *
631  * @dev:            Pointer to a struct drm_device.
632  * @data:           Pointer to data copied from / to user-space.
633  * @file_priv:      Pointer to a drm file private structure.
634  */
635 int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
636 			      struct drm_file *file_priv)
637 {
638 	struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
639 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
640 
641 	return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE);
642 }
643 
644 /**
645  * vmw_user_surface_define_ioctl - Ioctl function implementing
646  *                                  the user surface define functionality.
647  *
648  * @dev:            Pointer to a struct drm_device.
649  * @data:           Pointer to data copied from / to user-space.
650  * @file_priv:      Pointer to a drm file private structure.
651  */
652 int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
653 			     struct drm_file *file_priv)
654 {
655 	struct vmw_private *dev_priv = vmw_priv(dev);
656 	struct vmw_user_surface *user_srf;
657 	struct vmw_surface *srf;
658 	struct vmw_resource *res;
659 	struct vmw_resource *tmp;
660 	union drm_vmw_surface_create_arg *arg =
661 	    (union drm_vmw_surface_create_arg *)data;
662 	struct drm_vmw_surface_create_req *req = &arg->req;
663 	struct drm_vmw_surface_arg *rep = &arg->rep;
664 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
665 	struct drm_vmw_size __user *user_sizes;
666 	int ret;
667 	int i, j;
668 	uint32_t cur_bo_offset;
669 	struct drm_vmw_size *cur_size;
670 	struct vmw_surface_offset *cur_offset;
671 	uint32_t num_sizes;
672 	uint32_t size;
673 	struct vmw_master *vmaster = vmw_master(file_priv->master);
674 	const struct svga3d_surface_desc *desc;
675 
676 	if (unlikely(vmw_user_surface_size == 0))
677 		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
678 			128;
679 
680 	num_sizes = 0;
681 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
682 		num_sizes += req->mip_levels[i];
683 
684 	if (num_sizes > DRM_VMW_MAX_SURFACE_FACES *
685 	    DRM_VMW_MAX_MIP_LEVELS)
686 		return -EINVAL;
687 
688 	size = vmw_user_surface_size + 128 +
689 		ttm_round_pot(num_sizes * sizeof(struct drm_vmw_size)) +
690 		ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset));
691 
692 
693 	desc = svga3dsurface_get_desc(req->format);
694 	if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
695 		DRM_ERROR("Invalid surface format for surface creation.\n");
696 		return -EINVAL;
697 	}
698 
699 	ret = ttm_read_lock(&vmaster->lock, true);
700 	if (unlikely(ret != 0))
701 		return ret;
702 
703 	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
704 				   size, false, true);
705 	if (unlikely(ret != 0)) {
706 		if (ret != -ERESTARTSYS)
707 			DRM_ERROR("Out of graphics memory for surface"
708 				  " creation.\n");
709 		goto out_unlock;
710 	}
711 
712 	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
713 	if (unlikely(user_srf == NULL)) {
714 		ret = -ENOMEM;
715 		goto out_no_user_srf;
716 	}
717 
718 	srf = &user_srf->srf;
719 	res = &srf->res;
720 
721 	srf->flags = req->flags;
722 	srf->format = req->format;
723 	srf->scanout = req->scanout;
724 
725 	memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels));
726 	srf->num_sizes = num_sizes;
727 	user_srf->size = size;
728 
729 	srf->sizes = kmalloc(srf->num_sizes * sizeof(*srf->sizes), GFP_KERNEL);
730 	if (unlikely(srf->sizes == NULL)) {
731 		ret = -ENOMEM;
732 		goto out_no_sizes;
733 	}
734 	srf->offsets = kmalloc(srf->num_sizes * sizeof(*srf->offsets),
735 			       GFP_KERNEL);
736 	if (unlikely(srf->sizes == NULL)) {
737 		ret = -ENOMEM;
738 		goto out_no_offsets;
739 	}
740 
741 	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
742 	    req->size_addr;
743 
744 	ret = copy_from_user(srf->sizes, user_sizes,
745 			     srf->num_sizes * sizeof(*srf->sizes));
746 	if (unlikely(ret != 0)) {
747 		ret = -EFAULT;
748 		goto out_no_copy;
749 	}
750 
751 	srf->base_size = *srf->sizes;
752 	srf->autogen_filter = SVGA3D_TEX_FILTER_NONE;
753 	srf->multisample_count = 1;
754 
755 	cur_bo_offset = 0;
756 	cur_offset = srf->offsets;
757 	cur_size = srf->sizes;
758 
759 	for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
760 		for (j = 0; j < srf->mip_levels[i]; ++j) {
761 			uint32_t stride = svga3dsurface_calculate_pitch
762 				(desc, cur_size);
763 
764 			cur_offset->face = i;
765 			cur_offset->mip = j;
766 			cur_offset->bo_offset = cur_bo_offset;
767 			cur_bo_offset += svga3dsurface_get_image_buffer_size
768 				(desc, cur_size, stride);
769 			++cur_offset;
770 			++cur_size;
771 		}
772 	}
773 	res->backup_size = cur_bo_offset;
774 	if (srf->scanout &&
775 	    srf->num_sizes == 1 &&
776 	    srf->sizes[0].width == 64 &&
777 	    srf->sizes[0].height == 64 &&
778 	    srf->format == SVGA3D_A8R8G8B8) {
779 
780 		srf->snooper.image = kmalloc(64 * 64 * 4, GFP_KERNEL);
781 		/* clear the image */
782 		if (srf->snooper.image) {
783 			memset(srf->snooper.image, 0x00, 64 * 64 * 4);
784 		} else {
785 			DRM_ERROR("Failed to allocate cursor_image\n");
786 			ret = -ENOMEM;
787 			goto out_no_copy;
788 		}
789 	} else {
790 		srf->snooper.image = NULL;
791 	}
792 	srf->snooper.crtc = NULL;
793 
794 	user_srf->prime.base.shareable = false;
795 	user_srf->prime.base.tfile = NULL;
796 
797 	/**
798 	 * From this point, the generic resource management functions
799 	 * destroy the object on failure.
800 	 */
801 
802 	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
803 	if (unlikely(ret != 0))
804 		goto out_unlock;
805 
806 	tmp = vmw_resource_reference(&srf->res);
807 	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
808 				    req->shareable, VMW_RES_SURFACE,
809 				    &vmw_user_surface_base_release, NULL);
810 
811 	if (unlikely(ret != 0)) {
812 		vmw_resource_unreference(&tmp);
813 		vmw_resource_unreference(&res);
814 		goto out_unlock;
815 	}
816 
817 	rep->sid = user_srf->prime.base.hash.key;
818 	vmw_resource_unreference(&res);
819 
820 	ttm_read_unlock(&vmaster->lock);
821 	return 0;
822 out_no_copy:
823 	kfree(srf->offsets);
824 out_no_offsets:
825 	kfree(srf->sizes);
826 out_no_sizes:
827 	ttm_prime_object_kfree(user_srf, prime);
828 out_no_user_srf:
829 	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
830 out_unlock:
831 	ttm_read_unlock(&vmaster->lock);
832 	return ret;
833 }
834 
835 /**
836  * vmw_user_surface_define_ioctl - Ioctl function implementing
837  *                                  the user surface reference functionality.
838  *
839  * @dev:            Pointer to a struct drm_device.
840  * @data:           Pointer to data copied from / to user-space.
841  * @file_priv:      Pointer to a drm file private structure.
842  */
843 int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
844 				struct drm_file *file_priv)
845 {
846 	union drm_vmw_surface_reference_arg *arg =
847 	    (union drm_vmw_surface_reference_arg *)data;
848 	struct drm_vmw_surface_arg *req = &arg->req;
849 	struct drm_vmw_surface_create_req *rep = &arg->rep;
850 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
851 	struct vmw_surface *srf;
852 	struct vmw_user_surface *user_srf;
853 	struct drm_vmw_size __user *user_sizes;
854 	struct ttm_base_object *base;
855 	int ret = -EINVAL;
856 
857 	base = ttm_base_object_lookup(tfile, req->sid);
858 	if (unlikely(base == NULL)) {
859 		DRM_ERROR("Could not find surface to reference.\n");
860 		return -EINVAL;
861 	}
862 
863 	if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE))
864 		goto out_bad_resource;
865 
866 	user_srf = container_of(base, struct vmw_user_surface, prime.base);
867 	srf = &user_srf->srf;
868 
869 	ret = ttm_ref_object_add(tfile, &user_srf->prime.base,
870 				 TTM_REF_USAGE, NULL);
871 	if (unlikely(ret != 0)) {
872 		DRM_ERROR("Could not add a reference to a surface.\n");
873 		goto out_no_reference;
874 	}
875 
876 	rep->flags = srf->flags;
877 	rep->format = srf->format;
878 	memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels));
879 	user_sizes = (struct drm_vmw_size __user *)(unsigned long)
880 	    rep->size_addr;
881 
882 	if (user_sizes)
883 		ret = copy_to_user(user_sizes, srf->sizes,
884 				   srf->num_sizes * sizeof(*srf->sizes));
885 	if (unlikely(ret != 0)) {
886 		DRM_ERROR("copy_to_user failed %p %u\n",
887 			  user_sizes, srf->num_sizes);
888 		ret = -EFAULT;
889 	}
890 out_bad_resource:
891 out_no_reference:
892 	ttm_base_object_unref(&base);
893 
894 	return ret;
895 }
896