LCOV - code coverage report
Current view: top level - drivers/gpu/drm/virtio - virtgpu_gem.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 132 0.0 %
Date: 2022-04-01 14:17:54 Functions: 0 14 0.0 %
Branches: 0 44 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2015 Red Hat, Inc.
       3                 :            :  * All Rights Reserved.
       4                 :            :  *
       5                 :            :  * Permission is hereby granted, free of charge, to any person obtaining
       6                 :            :  * a copy of this software and associated documentation files (the
       7                 :            :  * "Software"), to deal in the Software without restriction, including
       8                 :            :  * without limitation the rights to use, copy, modify, merge, publish,
       9                 :            :  * distribute, sublicense, and/or sell copies of the Software, and to
      10                 :            :  * permit persons to whom the Software is furnished to do so, subject to
      11                 :            :  * the following conditions:
      12                 :            :  *
      13                 :            :  * The above copyright notice and this permission notice (including the
      14                 :            :  * next paragraph) shall be included in all copies or substantial
      15                 :            :  * portions of the Software.
      16                 :            :  *
      17                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      18                 :            :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      19                 :            :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      20                 :            :  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
      21                 :            :  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      22                 :            :  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      23                 :            :  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <drm/drm_file.h>
      27                 :            : #include <drm/drm_fourcc.h>
      28                 :            : 
      29                 :            : #include "virtgpu_drv.h"
      30                 :            : 
      31                 :          0 : int virtio_gpu_gem_create(struct drm_file *file,
      32                 :            :                           struct drm_device *dev,
      33                 :            :                           struct virtio_gpu_object_params *params,
      34                 :            :                           struct drm_gem_object **obj_p,
      35                 :            :                           uint32_t *handle_p)
      36                 :            : {
      37                 :          0 :         struct virtio_gpu_device *vgdev = dev->dev_private;
      38                 :          0 :         struct virtio_gpu_object *obj;
      39                 :          0 :         int ret;
      40                 :          0 :         u32 handle;
      41                 :            : 
      42                 :          0 :         ret = virtio_gpu_object_create(vgdev, params, &obj, NULL);
      43         [ #  # ]:          0 :         if (ret < 0)
      44                 :            :                 return ret;
      45                 :            : 
      46                 :          0 :         ret = drm_gem_handle_create(file, &obj->base.base, &handle);
      47         [ #  # ]:          0 :         if (ret) {
      48                 :          0 :                 drm_gem_object_release(&obj->base.base);
      49                 :          0 :                 return ret;
      50                 :            :         }
      51                 :            : 
      52                 :          0 :         *obj_p = &obj->base.base;
      53                 :            : 
      54                 :            :         /* drop reference from allocate - handle holds it now */
      55                 :          0 :         drm_gem_object_put_unlocked(&obj->base.base);
      56                 :            : 
      57                 :          0 :         *handle_p = handle;
      58                 :          0 :         return 0;
      59                 :            : }
      60                 :            : 
      61                 :          0 : int virtio_gpu_mode_dumb_create(struct drm_file *file_priv,
      62                 :            :                                 struct drm_device *dev,
      63                 :            :                                 struct drm_mode_create_dumb *args)
      64                 :            : {
      65                 :          0 :         struct drm_gem_object *gobj;
      66                 :          0 :         struct virtio_gpu_object_params params = { 0 };
      67                 :          0 :         int ret;
      68                 :          0 :         uint32_t pitch;
      69                 :            : 
      70         [ #  # ]:          0 :         if (args->bpp != 32)
      71                 :            :                 return -EINVAL;
      72                 :            : 
      73                 :          0 :         pitch = args->width * 4;
      74                 :          0 :         args->size = pitch * args->height;
      75                 :          0 :         args->size = ALIGN(args->size, PAGE_SIZE);
      76                 :            : 
      77                 :          0 :         params.format = virtio_gpu_translate_format(DRM_FORMAT_HOST_XRGB8888);
      78                 :          0 :         params.width = args->width;
      79                 :          0 :         params.height = args->height;
      80                 :          0 :         params.size = args->size;
      81                 :          0 :         params.dumb = true;
      82                 :          0 :         ret = virtio_gpu_gem_create(file_priv, dev, &params, &gobj,
      83                 :          0 :                                     &args->handle);
      84         [ #  # ]:          0 :         if (ret)
      85                 :          0 :                 goto fail;
      86                 :            : 
      87                 :          0 :         args->pitch = pitch;
      88                 :          0 :         return ret;
      89                 :            : 
      90                 :            : fail:
      91                 :          0 :         return ret;
      92                 :            : }
      93                 :            : 
      94                 :          0 : int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv,
      95                 :            :                               struct drm_device *dev,
      96                 :            :                               uint32_t handle, uint64_t *offset_p)
      97                 :            : {
      98                 :          0 :         struct drm_gem_object *gobj;
      99                 :            : 
     100         [ #  # ]:          0 :         BUG_ON(!offset_p);
     101                 :          0 :         gobj = drm_gem_object_lookup(file_priv, handle);
     102         [ #  # ]:          0 :         if (gobj == NULL)
     103                 :            :                 return -ENOENT;
     104                 :          0 :         *offset_p = drm_vma_node_offset_addr(&gobj->vma_node);
     105                 :          0 :         drm_gem_object_put_unlocked(gobj);
     106                 :          0 :         return 0;
     107                 :            : }
     108                 :            : 
     109                 :          0 : int virtio_gpu_gem_object_open(struct drm_gem_object *obj,
     110                 :            :                                struct drm_file *file)
     111                 :            : {
     112                 :          0 :         struct virtio_gpu_device *vgdev = obj->dev->dev_private;
     113                 :          0 :         struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
     114                 :          0 :         struct virtio_gpu_object_array *objs;
     115                 :            : 
     116         [ #  # ]:          0 :         if (!vgdev->has_virgl_3d)
     117                 :            :                 return 0;
     118                 :            : 
     119                 :          0 :         objs = virtio_gpu_array_alloc(1);
     120         [ #  # ]:          0 :         if (!objs)
     121                 :            :                 return -ENOMEM;
     122                 :          0 :         virtio_gpu_array_add_obj(objs, obj);
     123                 :            : 
     124                 :          0 :         virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id,
     125                 :            :                                                objs);
     126                 :          0 :         return 0;
     127                 :            : }
     128                 :            : 
     129                 :          0 : void virtio_gpu_gem_object_close(struct drm_gem_object *obj,
     130                 :            :                                  struct drm_file *file)
     131                 :            : {
     132                 :          0 :         struct virtio_gpu_device *vgdev = obj->dev->dev_private;
     133                 :          0 :         struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
     134                 :          0 :         struct virtio_gpu_object_array *objs;
     135                 :            : 
     136         [ #  # ]:          0 :         if (!vgdev->has_virgl_3d)
     137                 :            :                 return;
     138                 :            : 
     139                 :          0 :         objs = virtio_gpu_array_alloc(1);
     140         [ #  # ]:          0 :         if (!objs)
     141                 :            :                 return;
     142                 :          0 :         virtio_gpu_array_add_obj(objs, obj);
     143                 :            : 
     144                 :          0 :         virtio_gpu_cmd_context_detach_resource(vgdev, vfpriv->ctx_id,
     145                 :            :                                                objs);
     146                 :            : }
     147                 :            : 
     148                 :          0 : struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents)
     149                 :            : {
     150                 :          0 :         struct virtio_gpu_object_array *objs;
     151                 :          0 :         size_t size = sizeof(*objs) + sizeof(objs->objs[0]) * nents;
     152                 :            : 
     153         [ #  # ]:          0 :         objs = kmalloc(size, GFP_KERNEL);
     154         [ #  # ]:          0 :         if (!objs)
     155                 :            :                 return NULL;
     156                 :            : 
     157                 :          0 :         objs->nents = 0;
     158                 :          0 :         objs->total = nents;
     159                 :          0 :         return objs;
     160                 :            : }
     161                 :            : 
     162                 :          0 : static void virtio_gpu_array_free(struct virtio_gpu_object_array *objs)
     163                 :            : {
     164                 :          0 :         kfree(objs);
     165                 :            : }
     166                 :            : 
     167                 :            : struct virtio_gpu_object_array*
     168                 :          0 : virtio_gpu_array_from_handles(struct drm_file *drm_file, u32 *handles, u32 nents)
     169                 :            : {
     170                 :          0 :         struct virtio_gpu_object_array *objs;
     171                 :          0 :         u32 i;
     172                 :            : 
     173                 :          0 :         objs = virtio_gpu_array_alloc(nents);
     174         [ #  # ]:          0 :         if (!objs)
     175                 :            :                 return NULL;
     176                 :            : 
     177         [ #  # ]:          0 :         for (i = 0; i < nents; i++) {
     178                 :          0 :                 objs->objs[i] = drm_gem_object_lookup(drm_file, handles[i]);
     179         [ #  # ]:          0 :                 if (!objs->objs[i]) {
     180                 :          0 :                         objs->nents = i;
     181                 :          0 :                         virtio_gpu_array_put_free(objs);
     182                 :          0 :                         return NULL;
     183                 :            :                 }
     184                 :            :         }
     185                 :          0 :         objs->nents = i;
     186                 :          0 :         return objs;
     187                 :            : }
     188                 :            : 
     189                 :          0 : void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs,
     190                 :            :                               struct drm_gem_object *obj)
     191                 :            : {
     192   [ #  #  #  # ]:          0 :         if (WARN_ON_ONCE(objs->nents == objs->total))
     193                 :            :                 return;
     194                 :            : 
     195                 :          0 :         drm_gem_object_get(obj);
     196                 :          0 :         objs->objs[objs->nents] = obj;
     197                 :          0 :         objs->nents++;
     198                 :            : }
     199                 :            : 
     200                 :          0 : int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs)
     201                 :            : {
     202                 :          0 :         int ret;
     203                 :            : 
     204         [ #  # ]:          0 :         if (objs->nents == 1) {
     205                 :          0 :                 ret = dma_resv_lock_interruptible(objs->objs[0]->resv, NULL);
     206                 :            :         } else {
     207                 :          0 :                 ret = drm_gem_lock_reservations(objs->objs, objs->nents,
     208                 :            :                                                 &objs->ticket);
     209                 :            :         }
     210                 :          0 :         return ret;
     211                 :            : }
     212                 :            : 
     213                 :          0 : void virtio_gpu_array_unlock_resv(struct virtio_gpu_object_array *objs)
     214                 :            : {
     215         [ #  # ]:          0 :         if (objs->nents == 1) {
     216                 :          0 :                 dma_resv_unlock(objs->objs[0]->resv);
     217                 :            :         } else {
     218                 :          0 :                 drm_gem_unlock_reservations(objs->objs, objs->nents,
     219                 :            :                                             &objs->ticket);
     220                 :            :         }
     221                 :          0 : }
     222                 :            : 
     223                 :          0 : void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs,
     224                 :            :                                 struct dma_fence *fence)
     225                 :            : {
     226                 :          0 :         int i;
     227                 :            : 
     228         [ #  # ]:          0 :         for (i = 0; i < objs->nents; i++)
     229                 :          0 :                 dma_resv_add_excl_fence(objs->objs[i]->resv, fence);
     230                 :          0 : }
     231                 :            : 
     232                 :          0 : void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs)
     233                 :            : {
     234                 :          0 :         u32 i;
     235                 :            : 
     236         [ #  # ]:          0 :         for (i = 0; i < objs->nents; i++)
     237                 :          0 :                 drm_gem_object_put_unlocked(objs->objs[i]);
     238                 :          0 :         virtio_gpu_array_free(objs);
     239                 :          0 : }
     240                 :            : 
     241                 :          0 : void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev,
     242                 :            :                                        struct virtio_gpu_object_array *objs)
     243                 :            : {
     244                 :          0 :         spin_lock(&vgdev->obj_free_lock);
     245                 :          0 :         list_add_tail(&objs->next, &vgdev->obj_free_list);
     246                 :          0 :         spin_unlock(&vgdev->obj_free_lock);
     247                 :          0 :         schedule_work(&vgdev->obj_free_work);
     248                 :          0 : }
     249                 :            : 
     250                 :          0 : void virtio_gpu_array_put_free_work(struct work_struct *work)
     251                 :            : {
     252                 :          0 :         struct virtio_gpu_device *vgdev =
     253                 :          0 :                 container_of(work, struct virtio_gpu_device, obj_free_work);
     254                 :          0 :         struct virtio_gpu_object_array *objs;
     255                 :            : 
     256                 :          0 :         spin_lock(&vgdev->obj_free_lock);
     257         [ #  # ]:          0 :         while (!list_empty(&vgdev->obj_free_list)) {
     258                 :          0 :                 objs = list_first_entry(&vgdev->obj_free_list,
     259                 :            :                                         struct virtio_gpu_object_array, next);
     260                 :          0 :                 list_del(&objs->next);
     261                 :          0 :                 spin_unlock(&vgdev->obj_free_lock);
     262                 :          0 :                 virtio_gpu_array_put_free(objs);
     263                 :          0 :                 spin_lock(&vgdev->obj_free_lock);
     264                 :            :         }
     265                 :          0 :         spin_unlock(&vgdev->obj_free_lock);
     266                 :          0 : }

Generated by: LCOV version 1.14