linux/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
<<
>>
Prefs
   1/**************************************************************************
   2 *
   3 * Copyright © 2009 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 <drm/vmwgfx_drm.h>
  30#include <drm/ttm/ttm_object.h>
  31#include <drm/ttm/ttm_placement.h>
  32#include <drm/drmP.h>
  33
  34struct vmw_user_context {
  35        struct ttm_base_object base;
  36        struct vmw_resource res;
  37};
  38
  39struct vmw_user_surface {
  40        struct ttm_base_object base;
  41        struct vmw_surface srf;
  42        uint32_t size;
  43};
  44
  45struct vmw_user_dma_buffer {
  46        struct ttm_base_object base;
  47        struct vmw_dma_buffer dma;
  48};
  49
  50struct vmw_bo_user_rep {
  51        uint32_t handle;
  52        uint64_t map_handle;
  53};
  54
  55struct vmw_stream {
  56        struct vmw_resource res;
  57        uint32_t stream_id;
  58};
  59
  60struct vmw_user_stream {
  61        struct ttm_base_object base;
  62        struct vmw_stream stream;
  63};
  64
  65struct vmw_surface_offset {
  66        uint32_t face;
  67        uint32_t mip;
  68        uint32_t bo_offset;
  69};
  70
  71
  72static uint64_t vmw_user_context_size;
  73static uint64_t vmw_user_surface_size;
  74static uint64_t vmw_user_stream_size;
  75
  76static inline struct vmw_dma_buffer *
  77vmw_dma_buffer(struct ttm_buffer_object *bo)
  78{
  79        return container_of(bo, struct vmw_dma_buffer, base);
  80}
  81
  82static inline struct vmw_user_dma_buffer *
  83vmw_user_dma_buffer(struct ttm_buffer_object *bo)
  84{
  85        struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
  86        return container_of(vmw_bo, struct vmw_user_dma_buffer, dma);
  87}
  88
  89struct vmw_resource *vmw_resource_reference(struct vmw_resource *res)
  90{
  91        kref_get(&res->kref);
  92        return res;
  93}
  94
  95
  96/**
  97 * vmw_resource_release_id - release a resource id to the id manager.
  98 *
  99 * @res: Pointer to the resource.
 100 *
 101 * Release the resource id to the resource id manager and set it to -1
 102 */
 103static void vmw_resource_release_id(struct vmw_resource *res)
 104{
 105        struct vmw_private *dev_priv = res->dev_priv;
 106
 107        write_lock(&dev_priv->resource_lock);
 108        if (res->id != -1)
 109                idr_remove(res->idr, res->id);
 110        res->id = -1;
 111        write_unlock(&dev_priv->resource_lock);
 112}
 113
 114static void vmw_resource_release(struct kref *kref)
 115{
 116        struct vmw_resource *res =
 117            container_of(kref, struct vmw_resource, kref);
 118        struct vmw_private *dev_priv = res->dev_priv;
 119        int id = res->id;
 120        struct idr *idr = res->idr;
 121
 122        res->avail = false;
 123        if (res->remove_from_lists != NULL)
 124                res->remove_from_lists(res);
 125        write_unlock(&dev_priv->resource_lock);
 126
 127        if (likely(res->hw_destroy != NULL))
 128                res->hw_destroy(res);
 129
 130        if (res->res_free != NULL)
 131                res->res_free(res);
 132        else
 133                kfree(res);
 134
 135        write_lock(&dev_priv->resource_lock);
 136
 137        if (id != -1)
 138                idr_remove(idr, id);
 139}
 140
 141void vmw_resource_unreference(struct vmw_resource **p_res)
 142{
 143        struct vmw_resource *res = *p_res;
 144        struct vmw_private *dev_priv = res->dev_priv;
 145
 146        *p_res = NULL;
 147        write_lock(&dev_priv->resource_lock);
 148        kref_put(&res->kref, vmw_resource_release);
 149        write_unlock(&dev_priv->resource_lock);
 150}
 151
 152
 153/**
 154 * vmw_resource_alloc_id - release a resource id to the id manager.
 155 *
 156 * @dev_priv: Pointer to the device private structure.
 157 * @res: Pointer to the resource.
 158 *
 159 * Allocate the lowest free resource from the resource manager, and set
 160 * @res->id to that id. Returns 0 on success and -ENOMEM on failure.
 161 */
 162static int vmw_resource_alloc_id(struct vmw_private *dev_priv,
 163                                 struct vmw_resource *res)
 164{
 165        int ret;
 166
 167        BUG_ON(res->id != -1);
 168
 169        do {
 170                if (unlikely(idr_pre_get(res->idr, GFP_KERNEL) == 0))
 171                        return -ENOMEM;
 172
 173                write_lock(&dev_priv->resource_lock);
 174                ret = idr_get_new_above(res->idr, res, 1, &res->id);
 175                write_unlock(&dev_priv->resource_lock);
 176
 177        } while (ret == -EAGAIN);
 178
 179        return ret;
 180}
 181
 182
 183static int vmw_resource_init(struct vmw_private *dev_priv,
 184                             struct vmw_resource *res,
 185                             struct idr *idr,
 186                             enum ttm_object_type obj_type,
 187                             bool delay_id,
 188                             void (*res_free) (struct vmw_resource *res),
 189                             void (*remove_from_lists)
 190                             (struct vmw_resource *res))
 191{
 192        kref_init(&res->kref);
 193        res->hw_destroy = NULL;
 194        res->res_free = res_free;
 195        res->remove_from_lists = remove_from_lists;
 196        res->res_type = obj_type;
 197        res->idr = idr;
 198        res->avail = false;
 199        res->dev_priv = dev_priv;
 200        INIT_LIST_HEAD(&res->query_head);
 201        INIT_LIST_HEAD(&res->validate_head);
 202        res->id = -1;
 203        if (delay_id)
 204                return 0;
 205        else
 206                return vmw_resource_alloc_id(dev_priv, res);
 207}
 208
 209/**
 210 * vmw_resource_activate
 211 *
 212 * @res:        Pointer to the newly created resource
 213 * @hw_destroy: Destroy function. NULL if none.
 214 *
 215 * Activate a resource after the hardware has been made aware of it.
 216 * Set tye destroy function to @destroy. Typically this frees the
 217 * resource and destroys the hardware resources associated with it.
 218 * Activate basically means that the function vmw_resource_lookup will
 219 * find it.
 220 */
 221
 222static void vmw_resource_activate(struct vmw_resource *res,
 223                                  void (*hw_destroy) (struct vmw_resource *))
 224{
 225        struct vmw_private *dev_priv = res->dev_priv;
 226
 227        write_lock(&dev_priv->resource_lock);
 228        res->avail = true;
 229        res->hw_destroy = hw_destroy;
 230        write_unlock(&dev_priv->resource_lock);
 231}
 232
 233struct vmw_resource *vmw_resource_lookup(struct vmw_private *dev_priv,
 234                                         struct idr *idr, int id)
 235{
 236        struct vmw_resource *res;
 237
 238        read_lock(&dev_priv->resource_lock);
 239        res = idr_find(idr, id);
 240        if (res && res->avail)
 241                kref_get(&res->kref);
 242        else
 243                res = NULL;
 244        read_unlock(&dev_priv->resource_lock);
 245
 246        if (unlikely(res == NULL))
 247                return NULL;
 248
 249        return res;
 250}
 251
 252/**
 253 * Context management:
 254 */
 255
 256static void vmw_hw_context_destroy(struct vmw_resource *res)
 257{
 258
 259        struct vmw_private *dev_priv = res->dev_priv;
 260        struct {
 261                SVGA3dCmdHeader header;
 262                SVGA3dCmdDestroyContext body;
 263        } *cmd;
 264
 265
 266        vmw_execbuf_release_pinned_bo(dev_priv, true, res->id);
 267
 268        cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
 269        if (unlikely(cmd == NULL)) {
 270                DRM_ERROR("Failed reserving FIFO space for surface "
 271                          "destruction.\n");
 272                return;
 273        }
 274
 275        cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DESTROY);
 276        cmd->header.size = cpu_to_le32(sizeof(cmd->body));
 277        cmd->body.cid = cpu_to_le32(res->id);
 278
 279        vmw_fifo_commit(dev_priv, sizeof(*cmd));
 280        vmw_3d_resource_dec(dev_priv, false);
 281}
 282
 283static int vmw_context_init(struct vmw_private *dev_priv,
 284                            struct vmw_resource *res,
 285                            void (*res_free) (struct vmw_resource *res))
 286{
 287        int ret;
 288
 289        struct {
 290                SVGA3dCmdHeader header;
 291                SVGA3dCmdDefineContext body;
 292        } *cmd;
 293
 294        ret = vmw_resource_init(dev_priv, res, &dev_priv->context_idr,
 295                                VMW_RES_CONTEXT, false, res_free, NULL);
 296
 297        if (unlikely(ret != 0)) {
 298                DRM_ERROR("Failed to allocate a resource id.\n");
 299                goto out_early;
 300        }
 301
 302        if (unlikely(res->id >= SVGA3D_MAX_CONTEXT_IDS)) {
 303                DRM_ERROR("Out of hw context ids.\n");
 304                vmw_resource_unreference(&res);
 305                return -ENOMEM;
 306        }
 307
 308        cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
 309        if (unlikely(cmd == NULL)) {
 310                DRM_ERROR("Fifo reserve failed.\n");
 311                vmw_resource_unreference(&res);
 312                return -ENOMEM;
 313        }
 314
 315        cmd->header.id = cpu_to_le32(SVGA_3D_CMD_CONTEXT_DEFINE);
 316        cmd->header.size = cpu_to_le32(sizeof(cmd->body));
 317        cmd->body.cid = cpu_to_le32(res->id);
 318
 319        vmw_fifo_commit(dev_priv, sizeof(*cmd));
 320        (void) vmw_3d_resource_inc(dev_priv, false);
 321        vmw_resource_activate(res, vmw_hw_context_destroy);
 322        return 0;
 323
 324out_early:
 325        if (res_free == NULL)
 326                kfree(res);
 327        else
 328                res_free(res);
 329        return ret;
 330}
 331
 332struct vmw_resource *vmw_context_alloc(struct vmw_private *dev_priv)
 333{
 334        struct vmw_resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
 335        int ret;
 336
 337        if (unlikely(res == NULL))
 338                return NULL;
 339
 340        ret = vmw_context_init(dev_priv, res, NULL);
 341        return (ret == 0) ? res : NULL;
 342}
 343
 344/**
 345 * User-space context management:
 346 */
 347
 348static void vmw_user_context_free(struct vmw_resource *res)
 349{
 350        struct vmw_user_context *ctx =
 351            container_of(res, struct vmw_user_context, res);
 352        struct vmw_private *dev_priv = res->dev_priv;
 353
 354        kfree(ctx);
 355        ttm_mem_global_free(vmw_mem_glob(dev_priv),
 356                            vmw_user_context_size);
 357}
 358
 359/**
 360 * This function is called when user space has no more references on the
 361 * base object. It releases the base-object's reference on the resource object.
 362 */
 363
 364static void vmw_user_context_base_release(struct ttm_base_object **p_base)
 365{
 366        struct ttm_base_object *base = *p_base;
 367        struct vmw_user_context *ctx =
 368            container_of(base, struct vmw_user_context, base);
 369        struct vmw_resource *res = &ctx->res;
 370
 371        *p_base = NULL;
 372        vmw_resource_unreference(&res);
 373}
 374
 375int vmw_context_destroy_ioctl(struct drm_device *dev, void *data,
 376                              struct drm_file *file_priv)
 377{
 378        struct vmw_private *dev_priv = vmw_priv(dev);
 379        struct vmw_resource *res;
 380        struct vmw_user_context *ctx;
 381        struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
 382        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 383        int ret = 0;
 384
 385        res = vmw_resource_lookup(dev_priv, &dev_priv->context_idr, arg->cid);
 386        if (unlikely(res == NULL))
 387                return -EINVAL;
 388
 389        if (res->res_free != &vmw_user_context_free) {
 390                ret = -EINVAL;
 391                goto out;
 392        }
 393
 394        ctx = container_of(res, struct vmw_user_context, res);
 395        if (ctx->base.tfile != tfile && !ctx->base.shareable) {
 396                ret = -EPERM;
 397                goto out;
 398        }
 399
 400        ttm_ref_object_base_unref(tfile, ctx->base.hash.key, TTM_REF_USAGE);
 401out:
 402        vmw_resource_unreference(&res);
 403        return ret;
 404}
 405
 406int vmw_context_define_ioctl(struct drm_device *dev, void *data,
 407                             struct drm_file *file_priv)
 408{
 409        struct vmw_private *dev_priv = vmw_priv(dev);
 410        struct vmw_user_context *ctx;
 411        struct vmw_resource *res;
 412        struct vmw_resource *tmp;
 413        struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
 414        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 415        struct vmw_master *vmaster = vmw_master(file_priv->master);
 416        int ret;
 417
 418
 419        /*
 420         * Approximate idr memory usage with 128 bytes. It will be limited
 421         * by maximum number_of contexts anyway.
 422         */
 423
 424        if (unlikely(vmw_user_context_size == 0))
 425                vmw_user_context_size = ttm_round_pot(sizeof(*ctx)) + 128;
 426
 427        ret = ttm_read_lock(&vmaster->lock, true);
 428        if (unlikely(ret != 0))
 429                return ret;
 430
 431        ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
 432                                   vmw_user_context_size,
 433                                   false, true);
 434        if (unlikely(ret != 0)) {
 435                if (ret != -ERESTARTSYS)
 436                        DRM_ERROR("Out of graphics memory for context"
 437                                  " creation.\n");
 438                goto out_unlock;
 439        }
 440
 441        ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
 442        if (unlikely(ctx == NULL)) {
 443                ttm_mem_global_free(vmw_mem_glob(dev_priv),
 444                                    vmw_user_context_size);
 445                ret = -ENOMEM;
 446                goto out_unlock;
 447        }
 448
 449        res = &ctx->res;
 450        ctx->base.shareable = false;
 451        ctx->base.tfile = NULL;
 452
 453        /*
 454         * From here on, the destructor takes over resource freeing.
 455         */
 456
 457        ret = vmw_context_init(dev_priv, res, vmw_user_context_free);
 458        if (unlikely(ret != 0))
 459                goto out_unlock;
 460
 461        tmp = vmw_resource_reference(&ctx->res);
 462        ret = ttm_base_object_init(tfile, &ctx->base, false, VMW_RES_CONTEXT,
 463                                   &vmw_user_context_base_release, NULL);
 464
 465        if (unlikely(ret != 0)) {
 466                vmw_resource_unreference(&tmp);
 467                goto out_err;
 468        }
 469
 470        arg->cid = res->id;
 471out_err:
 472        vmw_resource_unreference(&res);
 473out_unlock:
 474        ttm_read_unlock(&vmaster->lock);
 475        return ret;
 476
 477}
 478
 479int vmw_context_check(struct vmw_private *dev_priv,
 480                      struct ttm_object_file *tfile,
 481                      int id,
 482                      struct vmw_resource **p_res)
 483{
 484        struct vmw_resource *res;
 485        int ret = 0;
 486
 487        read_lock(&dev_priv->resource_lock);
 488        res = idr_find(&dev_priv->context_idr, id);
 489        if (res && res->avail) {
 490                struct vmw_user_context *ctx =
 491                        container_of(res, struct vmw_user_context, res);
 492                if (ctx->base.tfile != tfile && !ctx->base.shareable)
 493                        ret = -EPERM;
 494                if (p_res)
 495                        *p_res = vmw_resource_reference(res);
 496        } else
 497                ret = -EINVAL;
 498        read_unlock(&dev_priv->resource_lock);
 499
 500        return ret;
 501}
 502
 503struct vmw_bpp {
 504        uint8_t bpp;
 505        uint8_t s_bpp;
 506};
 507
 508/*
 509 * Size table for the supported SVGA3D surface formats. It consists of
 510 * two values. The bpp value and the s_bpp value which is short for
 511 * "stride bits per pixel" The values are given in such a way that the
 512 * minimum stride for the image is calculated using
 513 *
 514 * min_stride = w*s_bpp
 515 *
 516 * and the total memory requirement for the image is
 517 *
 518 * h*min_stride*bpp/s_bpp
 519 *
 520 */
 521static const struct vmw_bpp vmw_sf_bpp[] = {
 522        [SVGA3D_FORMAT_INVALID] = {0, 0},
 523        [SVGA3D_X8R8G8B8] = {32, 32},
 524        [SVGA3D_A8R8G8B8] = {32, 32},
 525        [SVGA3D_R5G6B5] = {16, 16},
 526        [SVGA3D_X1R5G5B5] = {16, 16},
 527        [SVGA3D_A1R5G5B5] = {16, 16},
 528        [SVGA3D_A4R4G4B4] = {16, 16},
 529        [SVGA3D_Z_D32] = {32, 32},
 530        [SVGA3D_Z_D16] = {16, 16},
 531        [SVGA3D_Z_D24S8] = {32, 32},
 532        [SVGA3D_Z_D15S1] = {16, 16},
 533        [SVGA3D_LUMINANCE8] = {8, 8},
 534        [SVGA3D_LUMINANCE4_ALPHA4] = {8, 8},
 535        [SVGA3D_LUMINANCE16] = {16, 16},
 536        [SVGA3D_LUMINANCE8_ALPHA8] = {16, 16},
 537        [SVGA3D_DXT1] = {4, 16},
 538        [SVGA3D_DXT2] = {8, 32},
 539        [SVGA3D_DXT3] = {8, 32},
 540        [SVGA3D_DXT4] = {8, 32},
 541        [SVGA3D_DXT5] = {8, 32},
 542        [SVGA3D_BUMPU8V8] = {16, 16},
 543        [SVGA3D_BUMPL6V5U5] = {16, 16},
 544        [SVGA3D_BUMPX8L8V8U8] = {32, 32},
 545        [SVGA3D_ARGB_S10E5] = {16, 16},
 546        [SVGA3D_ARGB_S23E8] = {32, 32},
 547        [SVGA3D_A2R10G10B10] = {32, 32},
 548        [SVGA3D_V8U8] = {16, 16},
 549        [SVGA3D_Q8W8V8U8] = {32, 32},
 550        [SVGA3D_CxV8U8] = {16, 16},
 551        [SVGA3D_X8L8V8U8] = {32, 32},
 552        [SVGA3D_A2W10V10U10] = {32, 32},
 553        [SVGA3D_ALPHA8] = {8, 8},
 554        [SVGA3D_R_S10E5] = {16, 16},
 555        [SVGA3D_R_S23E8] = {32, 32},
 556        [SVGA3D_RG_S10E5] = {16, 16},
 557        [SVGA3D_RG_S23E8] = {32, 32},
 558        [SVGA3D_BUFFER] = {8, 8},
 559        [SVGA3D_Z_D24X8] = {32, 32},
 560        [SVGA3D_V16U16] = {32, 32},
 561        [SVGA3D_G16R16] = {32, 32},
 562        [SVGA3D_A16B16G16R16] = {64,  64},
 563        [SVGA3D_UYVY] = {12, 12},
 564        [SVGA3D_YUY2] = {12, 12},
 565        [SVGA3D_NV12] = {12, 8},
 566        [SVGA3D_AYUV] = {32, 32},
 567        [SVGA3D_BC4_UNORM] = {4,  16},
 568        [SVGA3D_BC5_UNORM] = {8,  32},
 569        [SVGA3D_Z_DF16] = {16,  16},
 570        [SVGA3D_Z_DF24] = {24,  24},
 571        [SVGA3D_Z_D24S8_INT] = {32,  32}
 572};
 573
 574
 575/**
 576 * Surface management.
 577 */
 578
 579struct vmw_surface_dma {
 580        SVGA3dCmdHeader header;
 581        SVGA3dCmdSurfaceDMA body;
 582        SVGA3dCopyBox cb;
 583        SVGA3dCmdSurfaceDMASuffix suffix;
 584};
 585
 586struct vmw_surface_define {
 587        SVGA3dCmdHeader header;
 588        SVGA3dCmdDefineSurface body;
 589};
 590
 591struct vmw_surface_destroy {
 592        SVGA3dCmdHeader header;
 593        SVGA3dCmdDestroySurface body;
 594};
 595
 596
 597/**
 598 * vmw_surface_dma_size - Compute fifo size for a dma command.
 599 *
 600 * @srf: Pointer to a struct vmw_surface
 601 *
 602 * Computes the required size for a surface dma command for backup or
 603 * restoration of the surface represented by @srf.
 604 */
 605static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf)
 606{
 607        return srf->num_sizes * sizeof(struct vmw_surface_dma);
 608}
 609
 610
 611/**
 612 * vmw_surface_define_size - Compute fifo size for a surface define command.
 613 *
 614 * @srf: Pointer to a struct vmw_surface
 615 *
 616 * Computes the required size for a surface define command for the definition
 617 * of the surface represented by @srf.
 618 */
 619static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf)
 620{
 621        return sizeof(struct vmw_surface_define) + srf->num_sizes *
 622                sizeof(SVGA3dSize);
 623}
 624
 625
 626/**
 627 * vmw_surface_destroy_size - Compute fifo size for a surface destroy command.
 628 *
 629 * Computes the required size for a surface destroy command for the destruction
 630 * of a hw surface.
 631 */
 632static inline uint32_t vmw_surface_destroy_size(void)
 633{
 634        return sizeof(struct vmw_surface_destroy);
 635}
 636
 637/**
 638 * vmw_surface_destroy_encode - Encode a surface_destroy command.
 639 *
 640 * @id: The surface id
 641 * @cmd_space: Pointer to memory area in which the commands should be encoded.
 642 */
 643static void vmw_surface_destroy_encode(uint32_t id,
 644                                       void *cmd_space)
 645{
 646        struct vmw_surface_destroy *cmd = (struct vmw_surface_destroy *)
 647                cmd_space;
 648
 649        cmd->header.id = SVGA_3D_CMD_SURFACE_DESTROY;
 650        cmd->header.size = sizeof(cmd->body);
 651        cmd->body.sid = id;
 652}
 653
 654/**
 655 * vmw_surface_define_encode - Encode a surface_define command.
 656 *
 657 * @srf: Pointer to a struct vmw_surface object.
 658 * @cmd_space: Pointer to memory area in which the commands should be encoded.
 659 */
 660static void vmw_surface_define_encode(const struct vmw_surface *srf,
 661                                      void *cmd_space)
 662{
 663        struct vmw_surface_define *cmd = (struct vmw_surface_define *)
 664                cmd_space;
 665        struct drm_vmw_size *src_size;
 666        SVGA3dSize *cmd_size;
 667        uint32_t cmd_len;
 668        int i;
 669
 670        cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize);
 671
 672        cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE;
 673        cmd->header.size = cmd_len;
 674        cmd->body.sid = srf->res.id;
 675        cmd->body.surfaceFlags = srf->flags;
 676        cmd->body.format = cpu_to_le32(srf->format);
 677        for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
 678                cmd->body.face[i].numMipLevels = srf->mip_levels[i];
 679
 680        cmd += 1;
 681        cmd_size = (SVGA3dSize *) cmd;
 682        src_size = srf->sizes;
 683
 684        for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) {
 685                cmd_size->width = src_size->width;
 686                cmd_size->height = src_size->height;
 687                cmd_size->depth = src_size->depth;
 688        }
 689}
 690
 691
 692/**
 693 * vmw_surface_dma_encode - Encode a surface_dma command.
 694 *
 695 * @srf: Pointer to a struct vmw_surface object.
 696 * @cmd_space: Pointer to memory area in which the commands should be encoded.
 697 * @ptr: Pointer to an SVGAGuestPtr indicating where the surface contents
 698 * should be placed or read from.
 699 * @to_surface: Boolean whether to DMA to the surface or from the surface.
 700 */
 701static void vmw_surface_dma_encode(struct vmw_surface *srf,
 702                                   void *cmd_space,
 703                                   const SVGAGuestPtr *ptr,
 704                                   bool to_surface)
 705{
 706        uint32_t i;
 707        uint32_t bpp = vmw_sf_bpp[srf->format].bpp;
 708        uint32_t stride_bpp = vmw_sf_bpp[srf->format].s_bpp;
 709        struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space;
 710
 711        for (i = 0; i < srf->num_sizes; ++i) {
 712                SVGA3dCmdHeader *header = &cmd->header;
 713                SVGA3dCmdSurfaceDMA *body = &cmd->body;
 714                SVGA3dCopyBox *cb = &cmd->cb;
 715                SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix;
 716                const struct vmw_surface_offset *cur_offset = &srf->offsets[i];
 717                const struct drm_vmw_size *cur_size = &srf->sizes[i];
 718
 719                header->id = SVGA_3D_CMD_SURFACE_DMA;
 720                header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix);
 721
 722                body->guest.ptr = *ptr;
 723                body->guest.ptr.offset += cur_offset->bo_offset;
 724                body->guest.pitch = (cur_size->width * stride_bpp + 7) >> 3;
 725                body->host.sid = srf->res.id;
 726                body->host.face = cur_offset->face;
 727                body->host.mipmap = cur_offset->mip;
 728                body->transfer = ((to_surface) ?  SVGA3D_WRITE_HOST_VRAM :
 729                                  SVGA3D_READ_HOST_VRAM);
 730                cb->x = 0;
 731                cb->y = 0;
 732                cb->z = 0;
 733                cb->srcx = 0;
 734                cb->srcy = 0;
 735                cb->srcz = 0;
 736                cb->w = cur_size->width;
 737                cb->h = cur_size->height;
 738                cb->d = cur_size->depth;
 739
 740                suffix->suffixSize = sizeof(*suffix);
 741                suffix->maximumOffset = body->guest.pitch*cur_size->height*
 742                        cur_size->depth*bpp / stride_bpp;
 743                suffix->flags.discard = 0;
 744                suffix->flags.unsynchronized = 0;
 745                suffix->flags.reserved = 0;
 746                ++cmd;
 747        }
 748};
 749
 750
 751static void vmw_hw_surface_destroy(struct vmw_resource *res)
 752{
 753
 754        struct vmw_private *dev_priv = res->dev_priv;
 755        struct vmw_surface *srf;
 756        void *cmd;
 757
 758        if (res->id != -1) {
 759
 760                cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size());
 761                if (unlikely(cmd == NULL)) {
 762                        DRM_ERROR("Failed reserving FIFO space for surface "
 763                                  "destruction.\n");
 764                        return;
 765                }
 766
 767                vmw_surface_destroy_encode(res->id, cmd);
 768                vmw_fifo_commit(dev_priv, vmw_surface_destroy_size());
 769
 770                /*
 771                 * used_memory_size_atomic, or separate lock
 772                 * to avoid taking dev_priv::cmdbuf_mutex in
 773                 * the destroy path.
 774                 */
 775
 776                mutex_lock(&dev_priv->cmdbuf_mutex);
 777                srf = container_of(res, struct vmw_surface, res);
 778                dev_priv->used_memory_size -= srf->backup_size;
 779                mutex_unlock(&dev_priv->cmdbuf_mutex);
 780
 781        }
 782        vmw_3d_resource_dec(dev_priv, false);
 783}
 784
 785void vmw_surface_res_free(struct vmw_resource *res)
 786{
 787        struct vmw_surface *srf = container_of(res, struct vmw_surface, res);
 788
 789        if (srf->backup)
 790                ttm_bo_unref(&srf->backup);
 791        kfree(srf->offsets);
 792        kfree(srf->sizes);
 793        kfree(srf->snooper.image);
 794        kfree(srf);
 795}
 796
 797
 798/**
 799 * vmw_surface_do_validate - make a surface available to the device.
 800 *
 801 * @dev_priv: Pointer to a device private struct.
 802 * @srf: Pointer to a struct vmw_surface.
 803 *
 804 * If the surface doesn't have a hw id, allocate one, and optionally
 805 * DMA the backed up surface contents to the device.
 806 *
 807 * Returns -EBUSY if there wasn't sufficient device resources to
 808 * complete the validation. Retry after freeing up resources.
 809 *
 810 * May return other errors if the kernel is out of guest resources.
 811 */
 812int vmw_surface_do_validate(struct vmw_private *dev_priv,
 813                            struct vmw_surface *srf)
 814{
 815        struct vmw_resource *res = &srf->res;
 816        struct list_head val_list;
 817        struct ttm_validate_buffer val_buf;
 818        uint32_t submit_size;
 819        uint8_t *cmd;
 820        int ret;
 821
 822        if (likely(res->id != -1))
 823                return 0;
 824
 825        if (unlikely(dev_priv->used_memory_size + srf->backup_size >=
 826                     dev_priv->memory_size))
 827                return -EBUSY;
 828
 829        /*
 830         * Reserve- and validate the backup DMA bo.
 831         */
 832
 833        if (srf->backup) {
 834                INIT_LIST_HEAD(&val_list);
 835                val_buf.bo = ttm_bo_reference(srf->backup);
 836                val_buf.new_sync_obj_arg = (void *)((unsigned long)
 837                                                    DRM_VMW_FENCE_FLAG_EXEC);
 838                list_add_tail(&val_buf.head, &val_list);
 839                ret = ttm_eu_reserve_buffers(&val_list);
 840                if (unlikely(ret != 0))
 841                        goto out_no_reserve;
 842
 843                ret = ttm_bo_validate(srf->backup, &vmw_srf_placement,
 844                                      true, false, false);
 845                if (unlikely(ret != 0))
 846                        goto out_no_validate;
 847        }
 848
 849        /*
 850         * Alloc id for the resource.
 851         */
 852
 853        ret = vmw_resource_alloc_id(dev_priv, res);
 854        if (unlikely(ret != 0)) {
 855                DRM_ERROR("Failed to allocate a surface id.\n");
 856                goto out_no_id;
 857        }
 858        if (unlikely(res->id >= SVGA3D_MAX_SURFACE_IDS)) {
 859                ret = -EBUSY;
 860                goto out_no_fifo;
 861        }
 862
 863
 864        /*
 865         * Encode surface define- and dma commands.
 866         */
 867
 868        submit_size = vmw_surface_define_size(srf);
 869        if (srf->backup)
 870                submit_size += vmw_surface_dma_size(srf);
 871
 872        cmd = vmw_fifo_reserve(dev_priv, submit_size);
 873        if (unlikely(cmd == NULL)) {
 874                DRM_ERROR("Failed reserving FIFO space for surface "
 875                          "validation.\n");
 876                ret = -ENOMEM;
 877                goto out_no_fifo;
 878        }
 879
 880        vmw_surface_define_encode(srf, cmd);
 881        if (srf->backup) {
 882                SVGAGuestPtr ptr;
 883
 884                cmd += vmw_surface_define_size(srf);
 885                vmw_bo_get_guest_ptr(srf->backup, &ptr);
 886                vmw_surface_dma_encode(srf, cmd, &ptr, true);
 887        }
 888
 889        vmw_fifo_commit(dev_priv, submit_size);
 890
 891        /*
 892         * Create a fence object and fence the backup buffer.
 893         */
 894
 895        if (srf->backup) {
 896                struct vmw_fence_obj *fence;
 897
 898                (void) vmw_execbuf_fence_commands(NULL, dev_priv,
 899                                                  &fence, NULL);
 900                ttm_eu_fence_buffer_objects(&val_list, fence);
 901                if (likely(fence != NULL))
 902                        vmw_fence_obj_unreference(&fence);
 903                ttm_bo_unref(&val_buf.bo);
 904                ttm_bo_unref(&srf->backup);
 905        }
 906
 907        /*
 908         * Surface memory usage accounting.
 909         */
 910
 911        dev_priv->used_memory_size += srf->backup_size;
 912
 913        return 0;
 914
 915out_no_fifo:
 916        vmw_resource_release_id(res);
 917out_no_id:
 918out_no_validate:
 919        if (srf->backup)
 920                ttm_eu_backoff_reservation(&val_list);
 921out_no_reserve:
 922        if (srf->backup)
 923                ttm_bo_unref(&val_buf.bo);
 924        return ret;
 925}
 926
 927/**
 928 * vmw_surface_evict - Evict a hw surface.
 929 *
 930 * @dev_priv: Pointer to a device private struct.
 931 * @srf: Pointer to a struct vmw_surface
 932 *
 933 * DMA the contents of a hw surface to a backup guest buffer object,
 934 * and destroy the hw surface, releasing its id.
 935 */
 936int vmw_surface_evict(struct vmw_private *dev_priv,
 937                      struct vmw_surface *srf)
 938{
 939        struct vmw_resource *res = &srf->res;
 940        struct list_head val_list;
 941        struct ttm_validate_buffer val_buf;
 942        uint32_t submit_size;
 943        uint8_t *cmd;
 944        int ret;
 945        struct vmw_fence_obj *fence;
 946        SVGAGuestPtr ptr;
 947
 948        BUG_ON(res->id == -1);
 949
 950        /*
 951         * Create a surface backup buffer object.
 952         */
 953
 954        if (!srf->backup) {
 955                ret = ttm_bo_create(&dev_priv->bdev, srf->backup_size,
 956                                    ttm_bo_type_device,
 957                                    &vmw_srf_placement, 0, 0, true,
 958                                    NULL, &srf->backup);
 959                if (unlikely(ret != 0))
 960                        return ret;
 961        }
 962
 963        /*
 964         * Reserve- and validate the backup DMA bo.
 965         */
 966
 967        INIT_LIST_HEAD(&val_list);
 968        val_buf.bo = ttm_bo_reference(srf->backup);
 969        val_buf.new_sync_obj_arg = (void *)(unsigned long)
 970                DRM_VMW_FENCE_FLAG_EXEC;
 971        list_add_tail(&val_buf.head, &val_list);
 972        ret = ttm_eu_reserve_buffers(&val_list);
 973        if (unlikely(ret != 0))
 974                goto out_no_reserve;
 975
 976        ret = ttm_bo_validate(srf->backup, &vmw_srf_placement,
 977                              true, false, false);
 978        if (unlikely(ret != 0))
 979                goto out_no_validate;
 980
 981
 982        /*
 983         * Encode the dma- and surface destroy commands.
 984         */
 985
 986        submit_size = vmw_surface_dma_size(srf) + vmw_surface_destroy_size();
 987        cmd = vmw_fifo_reserve(dev_priv, submit_size);
 988        if (unlikely(cmd == NULL)) {
 989                DRM_ERROR("Failed reserving FIFO space for surface "
 990                          "eviction.\n");
 991                ret = -ENOMEM;
 992                goto out_no_fifo;
 993        }
 994
 995        vmw_bo_get_guest_ptr(srf->backup, &ptr);
 996        vmw_surface_dma_encode(srf, cmd, &ptr, false);
 997        cmd += vmw_surface_dma_size(srf);
 998        vmw_surface_destroy_encode(res->id, cmd);
 999        vmw_fifo_commit(dev_priv, submit_size);
1000
1001        /*
1002         * Surface memory usage accounting.
1003         */
1004
1005        dev_priv->used_memory_size -= srf->backup_size;
1006
1007        /*
1008         * Create a fence object and fence the DMA buffer.
1009         */
1010
1011        (void) vmw_execbuf_fence_commands(NULL, dev_priv,
1012                                          &fence, NULL);
1013        ttm_eu_fence_buffer_objects(&val_list, fence);
1014        if (likely(fence != NULL))
1015                vmw_fence_obj_unreference(&fence);
1016        ttm_bo_unref(&val_buf.bo);
1017
1018        /*
1019         * Release the surface ID.
1020         */
1021
1022        vmw_resource_release_id(res);
1023
1024        return 0;
1025
1026out_no_fifo:
1027out_no_validate:
1028        if (srf->backup)
1029                ttm_eu_backoff_reservation(&val_list);
1030out_no_reserve:
1031        ttm_bo_unref(&val_buf.bo);
1032        ttm_bo_unref(&srf->backup);
1033        return ret;
1034}
1035
1036
1037/**
1038 * vmw_surface_validate - make a surface available to the device, evicting
1039 * other surfaces if needed.
1040 *
1041 * @dev_priv: Pointer to a device private struct.
1042 * @srf: Pointer to a struct vmw_surface.
1043 *
1044 * Try to validate a surface and if it fails due to limited device resources,
1045 * repeatedly try to evict other surfaces until the request can be
1046 * acommodated.
1047 *
1048 * May return errors if out of resources.
1049 */
1050int vmw_surface_validate(struct vmw_private *dev_priv,
1051                         struct vmw_surface *srf)
1052{
1053        int ret;
1054        struct vmw_surface *evict_srf;
1055
1056        do {
1057                write_lock(&dev_priv->resource_lock);
1058                list_del_init(&srf->lru_head);
1059                write_unlock(&dev_priv->resource_lock);
1060
1061                ret = vmw_surface_do_validate(dev_priv, srf);
1062                if (likely(ret != -EBUSY))
1063                        break;
1064
1065                write_lock(&dev_priv->resource_lock);
1066                if (list_empty(&dev_priv->surface_lru)) {
1067                        DRM_ERROR("Out of device memory for surfaces.\n");
1068                        ret = -EBUSY;
1069                        write_unlock(&dev_priv->resource_lock);
1070                        break;
1071                }
1072
1073                evict_srf = vmw_surface_reference
1074                        (list_first_entry(&dev_priv->surface_lru,
1075                                          struct vmw_surface,
1076                                          lru_head));
1077                list_del_init(&evict_srf->lru_head);
1078
1079                write_unlock(&dev_priv->resource_lock);
1080                (void) vmw_surface_evict(dev_priv, evict_srf);
1081
1082                vmw_surface_unreference(&evict_srf);
1083
1084        } while (1);
1085
1086        if (unlikely(ret != 0 && srf->res.id != -1)) {
1087                write_lock(&dev_priv->resource_lock);
1088                list_add_tail(&srf->lru_head, &dev_priv->surface_lru);
1089                write_unlock(&dev_priv->resource_lock);
1090        }
1091
1092        return ret;
1093}
1094
1095
1096/**
1097 * vmw_surface_remove_from_lists - Remove surface resources from lookup lists
1098 *
1099 * @res: Pointer to a struct vmw_resource embedded in a struct vmw_surface
1100 *
1101 * As part of the resource destruction, remove the surface from any
1102 * lookup lists.
1103 */
1104static void vmw_surface_remove_from_lists(struct vmw_resource *res)
1105{
1106        struct vmw_surface *srf = container_of(res, struct vmw_surface, res);
1107
1108        list_del_init(&srf->lru_head);
1109}
1110
1111int vmw_surface_init(struct vmw_private *dev_priv,
1112                     struct vmw_surface *srf,
1113                     void (*res_free) (struct vmw_resource *res))
1114{
1115        int ret;
1116        struct vmw_resource *res = &srf->res;
1117
1118        BUG_ON(res_free == NULL);
1119        INIT_LIST_HEAD(&srf->lru_head);
1120        ret = vmw_resource_init(dev_priv, res, &dev_priv->surface_idr,
1121                                VMW_RES_SURFACE, true, res_free,
1122                                vmw_surface_remove_from_lists);
1123
1124        if (unlikely(ret != 0))
1125                res_free(res);
1126
1127        /*
1128         * The surface won't be visible to hardware until a
1129         * surface validate.
1130         */
1131
1132        (void) vmw_3d_resource_inc(dev_priv, false);
1133        vmw_resource_activate(res, vmw_hw_surface_destroy);
1134        return ret;
1135}
1136
1137static void vmw_user_surface_free(struct vmw_resource *res)
1138{
1139        struct vmw_surface *srf = container_of(res, struct vmw_surface, res);
1140        struct vmw_user_surface *user_srf =
1141            container_of(srf, struct vmw_user_surface, srf);
1142        struct vmw_private *dev_priv = srf->res.dev_priv;
1143        uint32_t size = user_srf->size;
1144
1145        if (srf->backup)
1146                ttm_bo_unref(&srf->backup);
1147        kfree(srf->offsets);
1148        kfree(srf->sizes);
1149        kfree(srf->snooper.image);
1150        kfree(user_srf);
1151        ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
1152}
1153
1154/**
1155 * vmw_resource_unreserve - unreserve resources previously reserved for
1156 * command submission.
1157 *
1158 * @list_head: list of resources to unreserve.
1159 *
1160 * Currently only surfaces are considered, and unreserving a surface
1161 * means putting it back on the device's surface lru list,
1162 * so that it can be evicted if necessary.
1163 * This function traverses the resource list and
1164 * checks whether resources are surfaces, and in that case puts them back
1165 * on the device's surface LRU list.
1166 */
1167void vmw_resource_unreserve(struct list_head *list)
1168{
1169        struct vmw_resource *res;
1170        struct vmw_surface *srf;
1171        rwlock_t *lock = NULL;
1172
1173        list_for_each_entry(res, list, validate_head) {
1174
1175                if (res->res_free != &vmw_surface_res_free &&
1176                    res->res_free != &vmw_user_surface_free)
1177                        continue;
1178
1179                if (unlikely(lock == NULL)) {
1180                        lock = &res->dev_priv->resource_lock;
1181                        write_lock(lock);
1182                }
1183
1184                srf = container_of(res, struct vmw_surface, res);
1185                list_del_init(&srf->lru_head);
1186                list_add_tail(&srf->lru_head, &res->dev_priv->surface_lru);
1187        }
1188
1189        if (lock != NULL)
1190                write_unlock(lock);
1191}
1192
1193/**
1194 * Helper function that looks either a surface or dmabuf.
1195 *
1196 * The pointer this pointed at by out_surf and out_buf needs to be null.
1197 */
1198int vmw_user_lookup_handle(struct vmw_private *dev_priv,
1199                           struct ttm_object_file *tfile,
1200                           uint32_t handle,
1201                           struct vmw_surface **out_surf,
1202                           struct vmw_dma_buffer **out_buf)
1203{
1204        int ret;
1205
1206        BUG_ON(*out_surf || *out_buf);
1207
1208        ret = vmw_user_surface_lookup_handle(dev_priv, tfile, handle, out_surf);
1209        if (!ret)
1210                return 0;
1211
1212        ret = vmw_user_dmabuf_lookup(tfile, handle, out_buf);
1213        return ret;
1214}
1215
1216
1217int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv,
1218                                   struct ttm_object_file *tfile,
1219                                   uint32_t handle, struct vmw_surface **out)
1220{
1221        struct vmw_resource *res;
1222        struct vmw_surface *srf;
1223        struct vmw_user_surface *user_srf;
1224        struct ttm_base_object *base;
1225        int ret = -EINVAL;
1226
1227        base = ttm_base_object_lookup(tfile, handle);
1228        if (unlikely(base == NULL))
1229                return -EINVAL;
1230
1231        if (unlikely(base->object_type != VMW_RES_SURFACE))
1232                goto out_bad_resource;
1233
1234        user_srf = container_of(base, struct vmw_user_surface, base);
1235        srf = &user_srf->srf;
1236        res = &srf->res;
1237
1238        read_lock(&dev_priv->resource_lock);
1239
1240        if (!res->avail || res->res_free != &vmw_user_surface_free) {
1241                read_unlock(&dev_priv->resource_lock);
1242                goto out_bad_resource;
1243        }
1244
1245        kref_get(&res->kref);
1246        read_unlock(&dev_priv->resource_lock);
1247
1248        *out = srf;
1249        ret = 0;
1250
1251out_bad_resource:
1252        ttm_base_object_unref(&base);
1253
1254        return ret;
1255}
1256
1257static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
1258{
1259        struct ttm_base_object *base = *p_base;
1260        struct vmw_user_surface *user_srf =
1261            container_of(base, struct vmw_user_surface, base);
1262        struct vmw_resource *res = &user_srf->srf.res;
1263
1264        *p_base = NULL;
1265        vmw_resource_unreference(&res);
1266}
1267
1268int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
1269                              struct drm_file *file_priv)
1270{
1271        struct drm_vmw_surface_arg *arg = (struct drm_vmw_surface_arg *)data;
1272        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1273
1274        return ttm_ref_object_base_unref(tfile, arg->sid, TTM_REF_USAGE);
1275}
1276
1277int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
1278                             struct drm_file *file_priv)
1279{
1280        struct vmw_private *dev_priv = vmw_priv(dev);
1281        struct vmw_user_surface *user_srf;
1282        struct vmw_surface *srf;
1283        struct vmw_resource *res;
1284        struct vmw_resource *tmp;
1285        union drm_vmw_surface_create_arg *arg =
1286            (union drm_vmw_surface_create_arg *)data;
1287        struct drm_vmw_surface_create_req *req = &arg->req;
1288        struct drm_vmw_surface_arg *rep = &arg->rep;
1289        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1290        struct drm_vmw_size __user *user_sizes;
1291        int ret;
1292        int i, j;
1293        uint32_t cur_bo_offset;
1294        struct drm_vmw_size *cur_size;
1295        struct vmw_surface_offset *cur_offset;
1296        uint32_t stride_bpp;
1297        uint32_t bpp;
1298        uint32_t num_sizes;
1299        uint32_t size;
1300        struct vmw_master *vmaster = vmw_master(file_priv->master);
1301
1302        if (unlikely(vmw_user_surface_size == 0))
1303                vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
1304                        128;
1305
1306        num_sizes = 0;
1307        for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i)
1308                num_sizes += req->mip_levels[i];
1309
1310        if (num_sizes > DRM_VMW_MAX_SURFACE_FACES *
1311            DRM_VMW_MAX_MIP_LEVELS)
1312                return -EINVAL;
1313
1314        size = vmw_user_surface_size + 128 +
1315                ttm_round_pot(num_sizes * sizeof(struct drm_vmw_size)) +
1316                ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset));
1317
1318
1319        ret = ttm_read_lock(&vmaster->lock, true);
1320        if (unlikely(ret != 0))
1321                return ret;
1322
1323        ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
1324                                   size, false, true);
1325        if (unlikely(ret != 0)) {
1326                if (ret != -ERESTARTSYS)
1327                        DRM_ERROR("Out of graphics memory for surface"
1328                                  " creation.\n");
1329                goto out_unlock;
1330        }
1331
1332        user_srf = kmalloc(sizeof(*user_srf), GFP_KERNEL);
1333        if (unlikely(user_srf == NULL)) {
1334                ret = -ENOMEM;
1335                goto out_no_user_srf;
1336        }
1337
1338        srf = &user_srf->srf;
1339        res = &srf->res;
1340
1341        srf->flags = req->flags;
1342        srf->format = req->format;
1343        srf->scanout = req->scanout;
1344        srf->backup = NULL;
1345
1346        memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels));
1347        srf->num_sizes = num_sizes;
1348        user_srf->size = size;
1349
1350        srf->sizes = kmalloc(srf->num_sizes * sizeof(*srf->sizes), GFP_KERNEL);
1351        if (unlikely(srf->sizes == NULL)) {
1352                ret = -ENOMEM;
1353                goto out_no_sizes;
1354        }
1355        srf->offsets = kmalloc(srf->num_sizes * sizeof(*srf->offsets),
1356                               GFP_KERNEL);
1357        if (unlikely(srf->sizes == NULL)) {
1358                ret = -ENOMEM;
1359                goto out_no_offsets;
1360        }
1361
1362        user_sizes = (struct drm_vmw_size __user *)(unsigned long)
1363            req->size_addr;
1364
1365        ret = copy_from_user(srf->sizes, user_sizes,
1366                             srf->num_sizes * sizeof(*srf->sizes));
1367        if (unlikely(ret != 0)) {
1368                ret = -EFAULT;
1369                goto out_no_copy;
1370        }
1371
1372        cur_bo_offset = 0;
1373        cur_offset = srf->offsets;
1374        cur_size = srf->sizes;
1375
1376        bpp = vmw_sf_bpp[srf->format].bpp;
1377        stride_bpp = vmw_sf_bpp[srf->format].s_bpp;
1378
1379        for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
1380                for (j = 0; j < srf->mip_levels[i]; ++j) {
1381                        uint32_t stride =
1382                                (cur_size->width * stride_bpp + 7) >> 3;
1383
1384                        cur_offset->face = i;
1385                        cur_offset->mip = j;
1386                        cur_offset->bo_offset = cur_bo_offset;
1387                        cur_bo_offset += stride * cur_size->height *
1388                                cur_size->depth * bpp / stride_bpp;
1389                        ++cur_offset;
1390                        ++cur_size;
1391                }
1392        }
1393        srf->backup_size = cur_bo_offset;
1394
1395        if (srf->scanout &&
1396            srf->num_sizes == 1 &&
1397            srf->sizes[0].width == 64 &&
1398            srf->sizes[0].height == 64 &&
1399            srf->format == SVGA3D_A8R8G8B8) {
1400
1401                /* allocate image area and clear it */
1402                srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL);
1403                if (!srf->snooper.image) {
1404                        DRM_ERROR("Failed to allocate cursor_image\n");
1405                        ret = -ENOMEM;
1406                        goto out_no_copy;
1407                }
1408        } else {
1409                srf->snooper.image = NULL;
1410        }
1411        srf->snooper.crtc = NULL;
1412
1413        user_srf->base.shareable = false;
1414        user_srf->base.tfile = NULL;
1415
1416        /**
1417         * From this point, the generic resource management functions
1418         * destroy the object on failure.
1419         */
1420
1421        ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
1422        if (unlikely(ret != 0))
1423                goto out_unlock;
1424
1425        tmp = vmw_resource_reference(&srf->res);
1426        ret = ttm_base_object_init(tfile, &user_srf->base,
1427                                   req->shareable, VMW_RES_SURFACE,
1428                                   &vmw_user_surface_base_release, NULL);
1429
1430        if (unlikely(ret != 0)) {
1431                vmw_resource_unreference(&tmp);
1432                vmw_resource_unreference(&res);
1433                goto out_unlock;
1434        }
1435
1436        rep->sid = user_srf->base.hash.key;
1437        if (rep->sid == SVGA3D_INVALID_ID)
1438                DRM_ERROR("Created bad Surface ID.\n");
1439
1440        vmw_resource_unreference(&res);
1441
1442        ttm_read_unlock(&vmaster->lock);
1443        return 0;
1444out_no_copy:
1445        kfree(srf->offsets);
1446out_no_offsets:
1447        kfree(srf->sizes);
1448out_no_sizes:
1449        kfree(user_srf);
1450out_no_user_srf:
1451        ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
1452out_unlock:
1453        ttm_read_unlock(&vmaster->lock);
1454        return ret;
1455}
1456
1457int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
1458                                struct drm_file *file_priv)
1459{
1460        union drm_vmw_surface_reference_arg *arg =
1461            (union drm_vmw_surface_reference_arg *)data;
1462        struct drm_vmw_surface_arg *req = &arg->req;
1463        struct drm_vmw_surface_create_req *rep = &arg->rep;
1464        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1465        struct vmw_surface *srf;
1466        struct vmw_user_surface *user_srf;
1467        struct drm_vmw_size __user *user_sizes;
1468        struct ttm_base_object *base;
1469        int ret = -EINVAL;
1470
1471        base = ttm_base_object_lookup(tfile, req->sid);
1472        if (unlikely(base == NULL)) {
1473                DRM_ERROR("Could not find surface to reference.\n");
1474                return -EINVAL;
1475        }
1476
1477        if (unlikely(base->object_type != VMW_RES_SURFACE))
1478                goto out_bad_resource;
1479
1480        user_srf = container_of(base, struct vmw_user_surface, base);
1481        srf = &user_srf->srf;
1482
1483        ret = ttm_ref_object_add(tfile, &user_srf->base, TTM_REF_USAGE, NULL);
1484        if (unlikely(ret != 0)) {
1485                DRM_ERROR("Could not add a reference to a surface.\n");
1486                goto out_no_reference;
1487        }
1488
1489        rep->flags = srf->flags;
1490        rep->format = srf->format;
1491        memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels));
1492        user_sizes = (struct drm_vmw_size __user *)(unsigned long)
1493            rep->size_addr;
1494
1495        if (user_sizes)
1496                ret = copy_to_user(user_sizes, srf->sizes,
1497                                   srf->num_sizes * sizeof(*srf->sizes));
1498        if (unlikely(ret != 0)) {
1499                DRM_ERROR("copy_to_user failed %p %u\n",
1500                          user_sizes, srf->num_sizes);
1501                ret = -EFAULT;
1502        }
1503out_bad_resource:
1504out_no_reference:
1505        ttm_base_object_unref(&base);
1506
1507        return ret;
1508}
1509
1510int vmw_surface_check(struct vmw_private *dev_priv,
1511                      struct ttm_object_file *tfile,
1512                      uint32_t handle, int *id)
1513{
1514        struct ttm_base_object *base;
1515        struct vmw_user_surface *user_srf;
1516
1517        int ret = -EPERM;
1518
1519        base = ttm_base_object_lookup(tfile, handle);
1520        if (unlikely(base == NULL))
1521                return -EINVAL;
1522
1523        if (unlikely(base->object_type != VMW_RES_SURFACE))
1524                goto out_bad_surface;
1525
1526        user_srf = container_of(base, struct vmw_user_surface, base);
1527        *id = user_srf->srf.res.id;
1528        ret = 0;
1529
1530out_bad_surface:
1531        /**
1532         * FIXME: May deadlock here when called from the
1533         * command parsing code.
1534         */
1535
1536        ttm_base_object_unref(&base);
1537        return ret;
1538}
1539
1540/**
1541 * Buffer management.
1542 */
1543void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo)
1544{
1545        struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
1546
1547        kfree(vmw_bo);
1548}
1549
1550int vmw_dmabuf_init(struct vmw_private *dev_priv,
1551                    struct vmw_dma_buffer *vmw_bo,
1552                    size_t size, struct ttm_placement *placement,
1553                    bool interruptible,
1554                    void (*bo_free) (struct ttm_buffer_object *bo))
1555{
1556        struct ttm_bo_device *bdev = &dev_priv->bdev;
1557        size_t acc_size;
1558        int ret;
1559
1560        BUG_ON(!bo_free);
1561
1562        acc_size = ttm_bo_acc_size(bdev, size, sizeof(struct vmw_dma_buffer));
1563        memset(vmw_bo, 0, sizeof(*vmw_bo));
1564
1565        INIT_LIST_HEAD(&vmw_bo->validate_list);
1566
1567        ret = ttm_bo_init(bdev, &vmw_bo->base, size,
1568                          ttm_bo_type_device, placement,
1569                          0, 0, interruptible,
1570                          NULL, acc_size, NULL, bo_free);
1571        return ret;
1572}
1573
1574static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo)
1575{
1576        struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo);
1577
1578        kfree(vmw_user_bo);
1579}
1580
1581static void vmw_user_dmabuf_release(struct ttm_base_object **p_base)
1582{
1583        struct vmw_user_dma_buffer *vmw_user_bo;
1584        struct ttm_base_object *base = *p_base;
1585        struct ttm_buffer_object *bo;
1586
1587        *p_base = NULL;
1588
1589        if (unlikely(base == NULL))
1590                return;
1591
1592        vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
1593        bo = &vmw_user_bo->dma.base;
1594        ttm_bo_unref(&bo);
1595}
1596
1597int vmw_dmabuf_alloc_ioctl(struct drm_device *dev, void *data,
1598                           struct drm_file *file_priv)
1599{
1600        struct vmw_private *dev_priv = vmw_priv(dev);
1601        union drm_vmw_alloc_dmabuf_arg *arg =
1602            (union drm_vmw_alloc_dmabuf_arg *)data;
1603        struct drm_vmw_alloc_dmabuf_req *req = &arg->req;
1604        struct drm_vmw_dmabuf_rep *rep = &arg->rep;
1605        struct vmw_user_dma_buffer *vmw_user_bo;
1606        struct ttm_buffer_object *tmp;
1607        struct vmw_master *vmaster = vmw_master(file_priv->master);
1608        int ret;
1609
1610        vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
1611        if (unlikely(vmw_user_bo == NULL))
1612                return -ENOMEM;
1613
1614        ret = ttm_read_lock(&vmaster->lock, true);
1615        if (unlikely(ret != 0)) {
1616                kfree(vmw_user_bo);
1617                return ret;
1618        }
1619
1620        ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, req->size,
1621                              &vmw_vram_sys_placement, true,
1622                              &vmw_user_dmabuf_destroy);
1623        if (unlikely(ret != 0))
1624                goto out_no_dmabuf;
1625
1626        tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
1627        ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
1628                                   &vmw_user_bo->base,
1629                                   false,
1630                                   ttm_buffer_type,
1631                                   &vmw_user_dmabuf_release, NULL);
1632        if (unlikely(ret != 0))
1633                goto out_no_base_object;
1634        else {
1635                rep->handle = vmw_user_bo->base.hash.key;
1636                rep->map_handle = vmw_user_bo->dma.base.addr_space_offset;
1637                rep->cur_gmr_id = vmw_user_bo->base.hash.key;
1638                rep->cur_gmr_offset = 0;
1639        }
1640
1641out_no_base_object:
1642        ttm_bo_unref(&tmp);
1643out_no_dmabuf:
1644        ttm_read_unlock(&vmaster->lock);
1645
1646        return ret;
1647}
1648
1649int vmw_dmabuf_unref_ioctl(struct drm_device *dev, void *data,
1650                           struct drm_file *file_priv)
1651{
1652        struct drm_vmw_unref_dmabuf_arg *arg =
1653            (struct drm_vmw_unref_dmabuf_arg *)data;
1654
1655        return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
1656                                         arg->handle,
1657                                         TTM_REF_USAGE);
1658}
1659
1660uint32_t vmw_dmabuf_validate_node(struct ttm_buffer_object *bo,
1661                                  uint32_t cur_validate_node)
1662{
1663        struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
1664
1665        if (likely(vmw_bo->on_validate_list))
1666                return vmw_bo->cur_validate_node;
1667
1668        vmw_bo->cur_validate_node = cur_validate_node;
1669        vmw_bo->on_validate_list = true;
1670
1671        return cur_validate_node;
1672}
1673
1674void vmw_dmabuf_validate_clear(struct ttm_buffer_object *bo)
1675{
1676        struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
1677
1678        vmw_bo->on_validate_list = false;
1679}
1680
1681int vmw_user_dmabuf_lookup(struct ttm_object_file *tfile,
1682                           uint32_t handle, struct vmw_dma_buffer **out)
1683{
1684        struct vmw_user_dma_buffer *vmw_user_bo;
1685        struct ttm_base_object *base;
1686
1687        base = ttm_base_object_lookup(tfile, handle);
1688        if (unlikely(base == NULL)) {
1689                printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
1690                       (unsigned long)handle);
1691                return -ESRCH;
1692        }
1693
1694        if (unlikely(base->object_type != ttm_buffer_type)) {
1695                ttm_base_object_unref(&base);
1696                printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
1697                       (unsigned long)handle);
1698                return -EINVAL;
1699        }
1700
1701        vmw_user_bo = container_of(base, struct vmw_user_dma_buffer, base);
1702        (void)ttm_bo_reference(&vmw_user_bo->dma.base);
1703        ttm_base_object_unref(&base);
1704        *out = &vmw_user_bo->dma;
1705
1706        return 0;
1707}
1708
1709/*
1710 * Stream management
1711 */
1712
1713static void vmw_stream_destroy(struct vmw_resource *res)
1714{
1715        struct vmw_private *dev_priv = res->dev_priv;
1716        struct vmw_stream *stream;
1717        int ret;
1718
1719        DRM_INFO("%s: unref\n", __func__);
1720        stream = container_of(res, struct vmw_stream, res);
1721
1722        ret = vmw_overlay_unref(dev_priv, stream->stream_id);
1723        WARN_ON(ret != 0);
1724}
1725
1726static int vmw_stream_init(struct vmw_private *dev_priv,
1727                           struct vmw_stream *stream,
1728                           void (*res_free) (struct vmw_resource *res))
1729{
1730        struct vmw_resource *res = &stream->res;
1731        int ret;
1732
1733        ret = vmw_resource_init(dev_priv, res, &dev_priv->stream_idr,
1734                                VMW_RES_STREAM, false, res_free, NULL);
1735
1736        if (unlikely(ret != 0)) {
1737                if (res_free == NULL)
1738                        kfree(stream);
1739                else
1740                        res_free(&stream->res);
1741                return ret;
1742        }
1743
1744        ret = vmw_overlay_claim(dev_priv, &stream->stream_id);
1745        if (ret) {
1746                vmw_resource_unreference(&res);
1747                return ret;
1748        }
1749
1750        DRM_INFO("%s: claimed\n", __func__);
1751
1752        vmw_resource_activate(&stream->res, vmw_stream_destroy);
1753        return 0;
1754}
1755
1756/**
1757 * User-space context management:
1758 */
1759
1760static void vmw_user_stream_free(struct vmw_resource *res)
1761{
1762        struct vmw_user_stream *stream =
1763            container_of(res, struct vmw_user_stream, stream.res);
1764        struct vmw_private *dev_priv = res->dev_priv;
1765
1766        kfree(stream);
1767        ttm_mem_global_free(vmw_mem_glob(dev_priv),
1768                            vmw_user_stream_size);
1769}
1770
1771/**
1772 * This function is called when user space has no more references on the
1773 * base object. It releases the base-object's reference on the resource object.
1774 */
1775
1776static void vmw_user_stream_base_release(struct ttm_base_object **p_base)
1777{
1778        struct ttm_base_object *base = *p_base;
1779        struct vmw_user_stream *stream =
1780            container_of(base, struct vmw_user_stream, base);
1781        struct vmw_resource *res = &stream->stream.res;
1782
1783        *p_base = NULL;
1784        vmw_resource_unreference(&res);
1785}
1786
1787int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
1788                           struct drm_file *file_priv)
1789{
1790        struct vmw_private *dev_priv = vmw_priv(dev);
1791        struct vmw_resource *res;
1792        struct vmw_user_stream *stream;
1793        struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
1794        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1795        int ret = 0;
1796
1797        res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, arg->stream_id);
1798        if (unlikely(res == NULL))
1799                return -EINVAL;
1800
1801        if (res->res_free != &vmw_user_stream_free) {
1802                ret = -EINVAL;
1803                goto out;
1804        }
1805
1806        stream = container_of(res, struct vmw_user_stream, stream.res);
1807        if (stream->base.tfile != tfile) {
1808                ret = -EINVAL;
1809                goto out;
1810        }
1811
1812        ttm_ref_object_base_unref(tfile, stream->base.hash.key, TTM_REF_USAGE);
1813out:
1814        vmw_resource_unreference(&res);
1815        return ret;
1816}
1817
1818int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
1819                           struct drm_file *file_priv)
1820{
1821        struct vmw_private *dev_priv = vmw_priv(dev);
1822        struct vmw_user_stream *stream;
1823        struct vmw_resource *res;
1824        struct vmw_resource *tmp;
1825        struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
1826        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1827        struct vmw_master *vmaster = vmw_master(file_priv->master);
1828        int ret;
1829
1830        /*
1831         * Approximate idr memory usage with 128 bytes. It will be limited
1832         * by maximum number_of streams anyway?
1833         */
1834
1835        if (unlikely(vmw_user_stream_size == 0))
1836                vmw_user_stream_size = ttm_round_pot(sizeof(*stream)) + 128;
1837
1838        ret = ttm_read_lock(&vmaster->lock, true);
1839        if (unlikely(ret != 0))
1840                return ret;
1841
1842        ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
1843                                   vmw_user_stream_size,
1844                                   false, true);
1845        if (unlikely(ret != 0)) {
1846                if (ret != -ERESTARTSYS)
1847                        DRM_ERROR("Out of graphics memory for stream"
1848                                  " creation.\n");
1849                goto out_unlock;
1850        }
1851
1852
1853        stream = kmalloc(sizeof(*stream), GFP_KERNEL);
1854        if (unlikely(stream == NULL)) {
1855                ttm_mem_global_free(vmw_mem_glob(dev_priv),
1856                                    vmw_user_stream_size);
1857                ret = -ENOMEM;
1858                goto out_unlock;
1859        }
1860
1861        res = &stream->stream.res;
1862        stream->base.shareable = false;
1863        stream->base.tfile = NULL;
1864
1865        /*
1866         * From here on, the destructor takes over resource freeing.
1867         */
1868
1869        ret = vmw_stream_init(dev_priv, &stream->stream, vmw_user_stream_free);
1870        if (unlikely(ret != 0))
1871                goto out_unlock;
1872
1873        tmp = vmw_resource_reference(res);
1874        ret = ttm_base_object_init(tfile, &stream->base, false, VMW_RES_STREAM,
1875                                   &vmw_user_stream_base_release, NULL);
1876
1877        if (unlikely(ret != 0)) {
1878                vmw_resource_unreference(&tmp);
1879                goto out_err;
1880        }
1881
1882        arg->stream_id = res->id;
1883out_err:
1884        vmw_resource_unreference(&res);
1885out_unlock:
1886        ttm_read_unlock(&vmaster->lock);
1887        return ret;
1888}
1889
1890int vmw_user_stream_lookup(struct vmw_private *dev_priv,
1891                           struct ttm_object_file *tfile,
1892                           uint32_t *inout_id, struct vmw_resource **out)
1893{
1894        struct vmw_user_stream *stream;
1895        struct vmw_resource *res;
1896        int ret;
1897
1898        res = vmw_resource_lookup(dev_priv, &dev_priv->stream_idr, *inout_id);
1899        if (unlikely(res == NULL))
1900                return -EINVAL;
1901
1902        if (res->res_free != &vmw_user_stream_free) {
1903                ret = -EINVAL;
1904                goto err_ref;
1905        }
1906
1907        stream = container_of(res, struct vmw_user_stream, stream.res);
1908        if (stream->base.tfile != tfile) {
1909                ret = -EPERM;
1910                goto err_ref;
1911        }
1912
1913        *inout_id = stream->stream.stream_id;
1914        *out = res;
1915        return 0;
1916err_ref:
1917        vmw_resource_unreference(&res);
1918        return ret;
1919}
1920
1921
1922int vmw_dumb_create(struct drm_file *file_priv,
1923                    struct drm_device *dev,
1924                    struct drm_mode_create_dumb *args)
1925{
1926        struct vmw_private *dev_priv = vmw_priv(dev);
1927        struct vmw_master *vmaster = vmw_master(file_priv->master);
1928        struct vmw_user_dma_buffer *vmw_user_bo;
1929        struct ttm_buffer_object *tmp;
1930        int ret;
1931
1932        args->pitch = args->width * ((args->bpp + 7) / 8);
1933        args->size = args->pitch * args->height;
1934
1935        vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL);
1936        if (vmw_user_bo == NULL)
1937                return -ENOMEM;
1938
1939        ret = ttm_read_lock(&vmaster->lock, true);
1940        if (ret != 0) {
1941                kfree(vmw_user_bo);
1942                return ret;
1943        }
1944
1945        ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size,
1946                              &vmw_vram_sys_placement, true,
1947                              &vmw_user_dmabuf_destroy);
1948        if (ret != 0)
1949                goto out_no_dmabuf;
1950
1951        tmp = ttm_bo_reference(&vmw_user_bo->dma.base);
1952        ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile,
1953                                   &vmw_user_bo->base,
1954                                   false,
1955                                   ttm_buffer_type,
1956                                   &vmw_user_dmabuf_release, NULL);
1957        if (unlikely(ret != 0))
1958                goto out_no_base_object;
1959
1960        args->handle = vmw_user_bo->base.hash.key;
1961
1962out_no_base_object:
1963        ttm_bo_unref(&tmp);
1964out_no_dmabuf:
1965        ttm_read_unlock(&vmaster->lock);
1966        return ret;
1967}
1968
1969int vmw_dumb_map_offset(struct drm_file *file_priv,
1970                        struct drm_device *dev, uint32_t handle,
1971                        uint64_t *offset)
1972{
1973        struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
1974        struct vmw_dma_buffer *out_buf;
1975        int ret;
1976
1977        ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf);
1978        if (ret != 0)
1979                return -EINVAL;
1980
1981        *offset = out_buf->base.addr_space_offset;
1982        vmw_dmabuf_unreference(&out_buf);
1983        return 0;
1984}
1985
1986int vmw_dumb_destroy(struct drm_file *file_priv,
1987                     struct drm_device *dev,
1988                     uint32_t handle)
1989{
1990        return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
1991                                         handle, TTM_REF_USAGE);
1992}
1993