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

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2008-2015 Intel Corporation
       3                 :            :  *
       4                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
       5                 :            :  * copy of this software and associated documentation files (the "Software"),
       6                 :            :  * to deal in the Software without restriction, including without limitation
       7                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
       9                 :            :  * Software is furnished to do so, subject to the following conditions:
      10                 :            :  *
      11                 :            :  * The above copyright notice and this permission notice (including the next
      12                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      13                 :            :  * Software.
      14                 :            :  *
      15                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      18                 :            :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      20                 :            :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      21                 :            :  * IN THE SOFTWARE.
      22                 :            :  *
      23                 :            :  * Authors:
      24                 :            :  *    Eric Anholt <eric@anholt.net>
      25                 :            :  *
      26                 :            :  */
      27                 :            : 
      28                 :            : #include <drm/drm_vma_manager.h>
      29                 :            : #include <drm/i915_drm.h>
      30                 :            : #include <linux/dma-fence-array.h>
      31                 :            : #include <linux/kthread.h>
      32                 :            : #include <linux/dma-resv.h>
      33                 :            : #include <linux/shmem_fs.h>
      34                 :            : #include <linux/slab.h>
      35                 :            : #include <linux/stop_machine.h>
      36                 :            : #include <linux/swap.h>
      37                 :            : #include <linux/pci.h>
      38                 :            : #include <linux/dma-buf.h>
      39                 :            : #include <linux/mman.h>
      40                 :            : 
      41                 :            : #include "display/intel_display.h"
      42                 :            : #include "display/intel_frontbuffer.h"
      43                 :            : 
      44                 :            : #include "gem/i915_gem_clflush.h"
      45                 :            : #include "gem/i915_gem_context.h"
      46                 :            : #include "gem/i915_gem_ioctls.h"
      47                 :            : #include "gem/i915_gem_mman.h"
      48                 :            : #include "gem/i915_gem_region.h"
      49                 :            : #include "gt/intel_engine_user.h"
      50                 :            : #include "gt/intel_gt.h"
      51                 :            : #include "gt/intel_gt_pm.h"
      52                 :            : #include "gt/intel_workarounds.h"
      53                 :            : 
      54                 :            : #include "i915_drv.h"
      55                 :            : #include "i915_trace.h"
      56                 :            : #include "i915_vgpu.h"
      57                 :            : 
      58                 :            : #include "intel_pm.h"
      59                 :            : 
      60                 :            : static int
      61                 :          0 : insert_mappable_node(struct i915_ggtt *ggtt, struct drm_mm_node *node, u32 size)
      62                 :            : {
      63                 :          0 :         int err;
      64                 :            : 
      65                 :          0 :         err = mutex_lock_interruptible(&ggtt->vm.mutex);
      66         [ #  # ]:          0 :         if (err)
      67                 :            :                 return err;
      68                 :            : 
      69                 :          0 :         memset(node, 0, sizeof(*node));
      70                 :          0 :         err = drm_mm_insert_node_in_range(&ggtt->vm.mm, node,
      71                 :            :                                           size, 0, I915_COLOR_UNEVICTABLE,
      72                 :            :                                           0, ggtt->mappable_end,
      73                 :            :                                           DRM_MM_INSERT_LOW);
      74                 :            : 
      75                 :          0 :         mutex_unlock(&ggtt->vm.mutex);
      76                 :            : 
      77                 :          0 :         return err;
      78                 :            : }
      79                 :            : 
      80                 :            : static void
      81                 :          0 : remove_mappable_node(struct i915_ggtt *ggtt, struct drm_mm_node *node)
      82                 :            : {
      83                 :          0 :         mutex_lock(&ggtt->vm.mutex);
      84                 :          0 :         drm_mm_remove_node(node);
      85                 :          0 :         mutex_unlock(&ggtt->vm.mutex);
      86                 :          0 : }
      87                 :            : 
      88                 :            : int
      89                 :          0 : i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
      90                 :            :                             struct drm_file *file)
      91                 :            : {
      92                 :          0 :         struct i915_ggtt *ggtt = &to_i915(dev)->ggtt;
      93                 :          0 :         struct drm_i915_gem_get_aperture *args = data;
      94                 :          0 :         struct i915_vma *vma;
      95                 :          0 :         u64 pinned;
      96                 :            : 
      97         [ #  # ]:          0 :         if (mutex_lock_interruptible(&ggtt->vm.mutex))
      98                 :            :                 return -EINTR;
      99                 :            : 
     100                 :          0 :         pinned = ggtt->vm.reserved;
     101         [ #  # ]:          0 :         list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link)
     102         [ #  # ]:          0 :                 if (i915_vma_is_pinned(vma))
     103                 :          0 :                         pinned += vma->node.size;
     104                 :            : 
     105                 :          0 :         mutex_unlock(&ggtt->vm.mutex);
     106                 :            : 
     107                 :          0 :         args->aper_size = ggtt->vm.total;
     108                 :          0 :         args->aper_available_size = args->aper_size - pinned;
     109                 :            : 
     110                 :          0 :         return 0;
     111                 :            : }
     112                 :            : 
     113                 :          0 : int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
     114                 :            :                            unsigned long flags)
     115                 :            : {
     116                 :          0 :         struct intel_runtime_pm *rpm = &to_i915(obj->base.dev)->runtime_pm;
     117                 :          0 :         LIST_HEAD(still_in_list);
     118                 :          0 :         intel_wakeref_t wakeref;
     119                 :          0 :         struct i915_vma *vma;
     120                 :          0 :         int ret;
     121                 :            : 
     122         [ #  # ]:          0 :         if (!atomic_read(&obj->bind_count))
     123                 :            :                 return 0;
     124                 :            : 
     125                 :            :         /*
     126                 :            :          * As some machines use ACPI to handle runtime-resume callbacks, and
     127                 :            :          * ACPI is quite kmalloc happy, we cannot resume beneath the vm->mutex
     128                 :            :          * as they are required by the shrinker. Ergo, we wake the device up
     129                 :            :          * first just in case.
     130                 :            :          */
     131                 :          0 :         wakeref = intel_runtime_pm_get(rpm);
     132                 :            : 
     133                 :          0 : try_again:
     134                 :          0 :         ret = 0;
     135                 :          0 :         spin_lock(&obj->vma.lock);
     136   [ #  #  #  #  :          0 :         while (!ret && (vma = list_first_entry_or_null(&obj->vma.list,
                   #  # ]
     137                 :            :                                                        struct i915_vma,
     138                 :            :                                                        obj_link))) {
     139                 :          0 :                 struct i915_address_space *vm = vma->vm;
     140                 :            : 
     141                 :          0 :                 list_move_tail(&vma->obj_link, &still_in_list);
     142         [ #  # ]:          0 :                 if (!i915_vma_is_bound(vma, I915_VMA_BIND_MASK))
     143                 :          0 :                         continue;
     144                 :            : 
     145                 :          0 :                 ret = -EAGAIN;
     146         [ #  # ]:          0 :                 if (!i915_vm_tryopen(vm))
     147                 :            :                         break;
     148                 :            : 
     149                 :            :                 /* Prevent vma being freed by i915_vma_parked as we unbind */
     150                 :          0 :                 vma = __i915_vma_get(vma);
     151                 :          0 :                 spin_unlock(&obj->vma.lock);
     152                 :            : 
     153         [ #  # ]:          0 :                 if (vma) {
     154                 :          0 :                         ret = -EBUSY;
     155   [ #  #  #  # ]:          0 :                         if (flags & I915_GEM_OBJECT_UNBIND_ACTIVE ||
     156                 :            :                             !i915_vma_is_active(vma))
     157                 :          0 :                                 ret = i915_vma_unbind(vma);
     158                 :            : 
     159                 :          0 :                         __i915_vma_put(vma);
     160                 :            :                 }
     161                 :            : 
     162                 :          0 :                 i915_vm_close(vm);
     163                 :          0 :                 spin_lock(&obj->vma.lock);
     164                 :            :         }
     165         [ #  # ]:          0 :         list_splice_init(&still_in_list, &obj->vma.list);
     166                 :          0 :         spin_unlock(&obj->vma.lock);
     167                 :            : 
     168   [ #  #  #  # ]:          0 :         if (ret == -EAGAIN && flags & I915_GEM_OBJECT_UNBIND_BARRIER) {
     169                 :          0 :                 rcu_barrier(); /* flush the i915_vm_release() */
     170                 :          0 :                 goto try_again;
     171                 :            :         }
     172                 :            : 
     173                 :          0 :         intel_runtime_pm_put(rpm, wakeref);
     174                 :            : 
     175                 :          0 :         return ret;
     176                 :            : }
     177                 :            : 
     178                 :            : static int
     179                 :            : i915_gem_phys_pwrite(struct drm_i915_gem_object *obj,
     180                 :            :                      struct drm_i915_gem_pwrite *args,
     181                 :            :                      struct drm_file *file)
     182                 :            : {
     183                 :            :         void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
     184                 :            :         char __user *user_data = u64_to_user_ptr(args->data_ptr);
     185                 :            : 
     186                 :            :         /*
     187                 :            :          * We manually control the domain here and pretend that it
     188                 :            :          * remains coherent i.e. in the GTT domain, like shmem_pwrite.
     189                 :            :          */
     190                 :            :         i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
     191                 :            : 
     192                 :            :         if (copy_from_user(vaddr, user_data, args->size))
     193                 :            :                 return -EFAULT;
     194                 :            : 
     195                 :            :         drm_clflush_virt_range(vaddr, args->size);
     196                 :            :         intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt);
     197                 :            : 
     198                 :            :         i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
     199                 :            :         return 0;
     200                 :            : }
     201                 :            : 
     202                 :            : static int
     203                 :          0 : i915_gem_create(struct drm_file *file,
     204                 :            :                 struct intel_memory_region *mr,
     205                 :            :                 u64 *size_p,
     206                 :            :                 u32 *handle_p)
     207                 :            : {
     208                 :          0 :         struct drm_i915_gem_object *obj;
     209                 :          0 :         u32 handle;
     210                 :          0 :         u64 size;
     211                 :          0 :         int ret;
     212                 :            : 
     213                 :          0 :         GEM_BUG_ON(!is_power_of_2(mr->min_page_size));
     214                 :          0 :         size = round_up(*size_p, mr->min_page_size);
     215         [ #  # ]:          0 :         if (size == 0)
     216                 :            :                 return -EINVAL;
     217                 :            : 
     218                 :            :         /* For most of the ABI (e.g. mmap) we think in system pages */
     219                 :          0 :         GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE));
     220                 :            : 
     221                 :            :         /* Allocate the new object */
     222                 :          0 :         obj = i915_gem_object_create_region(mr, size, 0);
     223         [ #  # ]:          0 :         if (IS_ERR(obj))
     224                 :          0 :                 return PTR_ERR(obj);
     225                 :            : 
     226                 :          0 :         ret = drm_gem_handle_create(file, &obj->base, &handle);
     227                 :            :         /* drop reference from allocate - handle holds it now */
     228                 :          0 :         i915_gem_object_put(obj);
     229         [ #  # ]:          0 :         if (ret)
     230                 :            :                 return ret;
     231                 :            : 
     232                 :          0 :         *handle_p = handle;
     233                 :          0 :         *size_p = size;
     234                 :          0 :         return 0;
     235                 :            : }
     236                 :            : 
     237                 :            : int
     238                 :          0 : i915_gem_dumb_create(struct drm_file *file,
     239                 :            :                      struct drm_device *dev,
     240                 :            :                      struct drm_mode_create_dumb *args)
     241                 :            : {
     242                 :          0 :         enum intel_memory_type mem_type;
     243                 :          0 :         int cpp = DIV_ROUND_UP(args->bpp, 8);
     244                 :          0 :         u32 format;
     245                 :            : 
     246   [ #  #  #  # ]:          0 :         switch (cpp) {
     247                 :            :         case 1:
     248                 :            :                 format = DRM_FORMAT_C8;
     249                 :            :                 break;
     250                 :          0 :         case 2:
     251                 :          0 :                 format = DRM_FORMAT_RGB565;
     252                 :          0 :                 break;
     253                 :          0 :         case 4:
     254                 :          0 :                 format = DRM_FORMAT_XRGB8888;
     255                 :          0 :                 break;
     256                 :            :         default:
     257                 :            :                 return -EINVAL;
     258                 :            :         }
     259                 :            : 
     260                 :            :         /* have to work out size/pitch and return them */
     261                 :          0 :         args->pitch = ALIGN(args->width * cpp, 64);
     262                 :            : 
     263                 :            :         /* align stride to page size so that we can remap */
     264         [ #  # ]:          0 :         if (args->pitch > intel_plane_fb_max_stride(to_i915(dev), format,
     265                 :            :                                                     DRM_FORMAT_MOD_LINEAR))
     266                 :          0 :                 args->pitch = ALIGN(args->pitch, 4096);
     267                 :            : 
     268         [ #  # ]:          0 :         if (args->pitch < args->width)
     269                 :            :                 return -EINVAL;
     270                 :            : 
     271         [ #  # ]:          0 :         args->size = mul_u32_u32(args->pitch, args->height);
     272                 :            : 
     273                 :          0 :         mem_type = INTEL_MEMORY_SYSTEM;
     274         [ #  # ]:          0 :         if (HAS_LMEM(to_i915(dev)))
     275                 :          0 :                 mem_type = INTEL_MEMORY_LOCAL;
     276                 :            : 
     277                 :          0 :         return i915_gem_create(file,
     278                 :            :                                intel_memory_region_by_type(to_i915(dev),
     279                 :            :                                                            mem_type),
     280                 :          0 :                                &args->size, &args->handle);
     281                 :            : }
     282                 :            : 
     283                 :            : /**
     284                 :            :  * Creates a new mm object and returns a handle to it.
     285                 :            :  * @dev: drm device pointer
     286                 :            :  * @data: ioctl data blob
     287                 :            :  * @file: drm file pointer
     288                 :            :  */
     289                 :            : int
     290                 :          0 : i915_gem_create_ioctl(struct drm_device *dev, void *data,
     291                 :            :                       struct drm_file *file)
     292                 :            : {
     293                 :          0 :         struct drm_i915_private *i915 = to_i915(dev);
     294                 :          0 :         struct drm_i915_gem_create *args = data;
     295                 :            : 
     296                 :          0 :         i915_gem_flush_free_objects(i915);
     297                 :            : 
     298                 :          0 :         return i915_gem_create(file,
     299                 :            :                                intel_memory_region_by_type(i915,
     300                 :            :                                                            INTEL_MEMORY_SYSTEM),
     301                 :          0 :                                &args->size, &args->handle);
     302                 :            : }
     303                 :            : 
     304                 :            : static int
     305                 :          0 : shmem_pread(struct page *page, int offset, int len, char __user *user_data,
     306                 :            :             bool needs_clflush)
     307                 :            : {
     308                 :          0 :         char *vaddr;
     309                 :          0 :         int ret;
     310                 :            : 
     311                 :          0 :         vaddr = kmap(page);
     312                 :            : 
     313         [ #  # ]:          0 :         if (needs_clflush)
     314                 :          0 :                 drm_clflush_virt_range(vaddr + offset, len);
     315                 :            : 
     316                 :          0 :         ret = __copy_to_user(user_data, vaddr + offset, len);
     317                 :            : 
     318         [ #  # ]:          0 :         kunmap(page);
     319                 :            : 
     320         [ #  # ]:          0 :         return ret ? -EFAULT : 0;
     321                 :            : }
     322                 :            : 
     323                 :            : static int
     324                 :          0 : i915_gem_shmem_pread(struct drm_i915_gem_object *obj,
     325                 :            :                      struct drm_i915_gem_pread *args)
     326                 :            : {
     327                 :          0 :         unsigned int needs_clflush;
     328                 :          0 :         unsigned int idx, offset;
     329                 :          0 :         struct dma_fence *fence;
     330                 :          0 :         char __user *user_data;
     331                 :          0 :         u64 remain;
     332                 :          0 :         int ret;
     333                 :            : 
     334                 :          0 :         ret = i915_gem_object_prepare_read(obj, &needs_clflush);
     335         [ #  # ]:          0 :         if (ret)
     336                 :            :                 return ret;
     337                 :            : 
     338                 :          0 :         fence = i915_gem_object_lock_fence(obj);
     339                 :          0 :         i915_gem_object_finish_access(obj);
     340         [ #  # ]:          0 :         if (!fence)
     341                 :            :                 return -ENOMEM;
     342                 :            : 
     343                 :          0 :         remain = args->size;
     344                 :          0 :         user_data = u64_to_user_ptr(args->data_ptr);
     345                 :          0 :         offset = offset_in_page(args->offset);
     346         [ #  # ]:          0 :         for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
     347                 :          0 :                 struct page *page = i915_gem_object_get_page(obj, idx);
     348                 :          0 :                 unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
     349                 :            : 
     350                 :          0 :                 ret = shmem_pread(page, offset, length, user_data,
     351                 :            :                                   needs_clflush);
     352         [ #  # ]:          0 :                 if (ret)
     353                 :            :                         break;
     354                 :            : 
     355                 :          0 :                 remain -= length;
     356                 :          0 :                 user_data += length;
     357                 :          0 :                 offset = 0;
     358                 :            :         }
     359                 :            : 
     360                 :          0 :         i915_gem_object_unlock_fence(obj, fence);
     361                 :          0 :         return ret;
     362                 :            : }
     363                 :            : 
     364                 :            : static inline bool
     365                 :          0 : gtt_user_read(struct io_mapping *mapping,
     366                 :            :               loff_t base, int offset,
     367                 :            :               char __user *user_data, int length)
     368                 :            : {
     369                 :          0 :         void __iomem *vaddr;
     370                 :          0 :         unsigned long unwritten;
     371                 :            : 
     372                 :            :         /* We can use the cpu mem copy function because this is X86. */
     373                 :          0 :         vaddr = io_mapping_map_atomic_wc(mapping, base);
     374                 :          0 :         unwritten = __copy_to_user_inatomic(user_data,
     375                 :          0 :                                             (void __force *)vaddr + offset,
     376                 :            :                                             length);
     377                 :          0 :         io_mapping_unmap_atomic(vaddr);
     378         [ #  # ]:          0 :         if (unwritten) {
     379         [ #  # ]:          0 :                 vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE);
     380                 :          0 :                 unwritten = copy_to_user(user_data,
     381         [ #  # ]:          0 :                                          (void __force *)vaddr + offset,
     382                 :            :                                          length);
     383                 :            :                 io_mapping_unmap(vaddr);
     384                 :            :         }
     385                 :          0 :         return unwritten;
     386                 :            : }
     387                 :            : 
     388                 :            : static int
     389                 :          0 : i915_gem_gtt_pread(struct drm_i915_gem_object *obj,
     390                 :            :                    const struct drm_i915_gem_pread *args)
     391                 :            : {
     392                 :          0 :         struct drm_i915_private *i915 = to_i915(obj->base.dev);
     393                 :          0 :         struct i915_ggtt *ggtt = &i915->ggtt;
     394                 :          0 :         intel_wakeref_t wakeref;
     395                 :          0 :         struct drm_mm_node node;
     396                 :          0 :         struct dma_fence *fence;
     397                 :          0 :         void __user *user_data;
     398                 :          0 :         struct i915_vma *vma;
     399                 :          0 :         u64 remain, offset;
     400                 :          0 :         int ret;
     401                 :            : 
     402                 :          0 :         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
     403         [ #  # ]:          0 :         vma = ERR_PTR(-ENODEV);
     404         [ #  # ]:          0 :         if (!i915_gem_object_is_tiled(obj))
     405                 :          0 :                 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
     406                 :            :                                                PIN_MAPPABLE |
     407                 :            :                                                PIN_NONBLOCK /* NOWARN */ |
     408                 :            :                                                PIN_NOEVICT);
     409         [ #  # ]:          0 :         if (!IS_ERR(vma)) {
     410                 :          0 :                 node.start = i915_ggtt_offset(vma);
     411                 :          0 :                 node.flags = 0;
     412                 :            :         } else {
     413                 :          0 :                 ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
     414         [ #  # ]:          0 :                 if (ret)
     415                 :          0 :                         goto out_rpm;
     416                 :          0 :                 GEM_BUG_ON(!drm_mm_node_allocated(&node));
     417                 :            :         }
     418                 :            : 
     419                 :          0 :         ret = i915_gem_object_lock_interruptible(obj);
     420         [ #  # ]:          0 :         if (ret)
     421                 :          0 :                 goto out_unpin;
     422                 :            : 
     423                 :          0 :         ret = i915_gem_object_set_to_gtt_domain(obj, false);
     424         [ #  # ]:          0 :         if (ret) {
     425                 :          0 :                 i915_gem_object_unlock(obj);
     426                 :          0 :                 goto out_unpin;
     427                 :            :         }
     428                 :            : 
     429                 :          0 :         fence = i915_gem_object_lock_fence(obj);
     430                 :          0 :         i915_gem_object_unlock(obj);
     431         [ #  # ]:          0 :         if (!fence) {
     432                 :          0 :                 ret = -ENOMEM;
     433                 :          0 :                 goto out_unpin;
     434                 :            :         }
     435                 :            : 
     436                 :          0 :         user_data = u64_to_user_ptr(args->data_ptr);
     437                 :          0 :         remain = args->size;
     438                 :          0 :         offset = args->offset;
     439                 :            : 
     440         [ #  # ]:          0 :         while (remain > 0) {
     441                 :            :                 /* Operation in this page
     442                 :            :                  *
     443                 :            :                  * page_base = page offset within aperture
     444                 :            :                  * page_offset = offset within page
     445                 :            :                  * page_length = bytes to copy for this page
     446                 :            :                  */
     447                 :          0 :                 u32 page_base = node.start;
     448                 :          0 :                 unsigned page_offset = offset_in_page(offset);
     449                 :          0 :                 unsigned page_length = PAGE_SIZE - page_offset;
     450                 :          0 :                 page_length = remain < page_length ? remain : page_length;
     451         [ #  # ]:          0 :                 if (drm_mm_node_allocated(&node)) {
     452                 :          0 :                         ggtt->vm.insert_page(&ggtt->vm,
     453                 :          0 :                                              i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
     454                 :            :                                              node.start, I915_CACHE_NONE, 0);
     455                 :            :                 } else {
     456                 :          0 :                         page_base += offset & PAGE_MASK;
     457                 :            :                 }
     458                 :            : 
     459         [ #  # ]:          0 :                 if (gtt_user_read(&ggtt->iomap, page_base, page_offset,
     460                 :            :                                   user_data, page_length)) {
     461                 :            :                         ret = -EFAULT;
     462                 :            :                         break;
     463                 :            :                 }
     464                 :            : 
     465                 :          0 :                 remain -= page_length;
     466                 :          0 :                 user_data += page_length;
     467                 :          0 :                 offset += page_length;
     468                 :            :         }
     469                 :            : 
     470                 :          0 :         i915_gem_object_unlock_fence(obj, fence);
     471                 :          0 : out_unpin:
     472         [ #  # ]:          0 :         if (drm_mm_node_allocated(&node)) {
     473                 :          0 :                 ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
     474                 :          0 :                 remove_mappable_node(ggtt, &node);
     475                 :            :         } else {
     476                 :          0 :                 i915_vma_unpin(vma);
     477                 :            :         }
     478                 :          0 : out_rpm:
     479                 :          0 :         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
     480                 :          0 :         return ret;
     481                 :            : }
     482                 :            : 
     483                 :            : /**
     484                 :            :  * Reads data from the object referenced by handle.
     485                 :            :  * @dev: drm device pointer
     486                 :            :  * @data: ioctl data blob
     487                 :            :  * @file: drm file pointer
     488                 :            :  *
     489                 :            :  * On error, the contents of *data are undefined.
     490                 :            :  */
     491                 :            : int
     492                 :          0 : i915_gem_pread_ioctl(struct drm_device *dev, void *data,
     493                 :            :                      struct drm_file *file)
     494                 :            : {
     495                 :          0 :         struct drm_i915_gem_pread *args = data;
     496                 :          0 :         struct drm_i915_gem_object *obj;
     497                 :          0 :         int ret;
     498                 :            : 
     499         [ #  # ]:          0 :         if (args->size == 0)
     500                 :            :                 return 0;
     501                 :            : 
     502   [ #  #  #  # ]:          0 :         if (!access_ok(u64_to_user_ptr(args->data_ptr),
     503                 :            :                        args->size))
     504                 :            :                 return -EFAULT;
     505                 :            : 
     506                 :          0 :         obj = i915_gem_object_lookup(file, args->handle);
     507         [ #  # ]:          0 :         if (!obj)
     508                 :            :                 return -ENOENT;
     509                 :            : 
     510                 :            :         /* Bounds check source.  */
     511   [ #  #  #  # ]:          0 :         if (range_overflows_t(u64, args->offset, args->size, obj->base.size)) {
     512                 :          0 :                 ret = -EINVAL;
     513                 :          0 :                 goto out;
     514                 :            :         }
     515                 :            : 
     516                 :          0 :         trace_i915_gem_object_pread(obj, args->offset, args->size);
     517                 :            : 
     518                 :          0 :         ret = i915_gem_object_wait(obj,
     519                 :            :                                    I915_WAIT_INTERRUPTIBLE,
     520                 :            :                                    MAX_SCHEDULE_TIMEOUT);
     521         [ #  # ]:          0 :         if (ret)
     522                 :          0 :                 goto out;
     523                 :            : 
     524                 :          0 :         ret = i915_gem_object_pin_pages(obj);
     525         [ #  # ]:          0 :         if (ret)
     526                 :          0 :                 goto out;
     527                 :            : 
     528                 :          0 :         ret = i915_gem_shmem_pread(obj, args);
     529         [ #  # ]:          0 :         if (ret == -EFAULT || ret == -ENODEV)
     530                 :          0 :                 ret = i915_gem_gtt_pread(obj, args);
     531                 :            : 
     532                 :          0 :         i915_gem_object_unpin_pages(obj);
     533                 :          0 : out:
     534                 :          0 :         i915_gem_object_put(obj);
     535                 :          0 :         return ret;
     536                 :            : }
     537                 :            : 
     538                 :            : /* This is the fast write path which cannot handle
     539                 :            :  * page faults in the source data
     540                 :            :  */
     541                 :            : 
     542                 :            : static inline bool
     543                 :          0 : ggtt_write(struct io_mapping *mapping,
     544                 :            :            loff_t base, int offset,
     545                 :            :            char __user *user_data, int length)
     546                 :            : {
     547                 :          0 :         void __iomem *vaddr;
     548                 :          0 :         unsigned long unwritten;
     549                 :            : 
     550                 :            :         /* We can use the cpu mem copy function because this is X86. */
     551                 :          0 :         vaddr = io_mapping_map_atomic_wc(mapping, base);
     552                 :          0 :         unwritten = __copy_from_user_inatomic_nocache((void __force *)vaddr + offset,
     553                 :            :                                                       user_data, length);
     554                 :          0 :         io_mapping_unmap_atomic(vaddr);
     555         [ #  # ]:          0 :         if (unwritten) {
     556         [ #  # ]:          0 :                 vaddr = io_mapping_map_wc(mapping, base, PAGE_SIZE);
     557         [ #  # ]:          0 :                 unwritten = copy_from_user((void __force *)vaddr + offset,
     558                 :            :                                            user_data, length);
     559                 :            :                 io_mapping_unmap(vaddr);
     560                 :            :         }
     561                 :            : 
     562                 :          0 :         return unwritten;
     563                 :            : }
     564                 :            : 
     565                 :            : /**
     566                 :            :  * This is the fast pwrite path, where we copy the data directly from the
     567                 :            :  * user into the GTT, uncached.
     568                 :            :  * @obj: i915 GEM object
     569                 :            :  * @args: pwrite arguments structure
     570                 :            :  */
     571                 :            : static int
     572                 :          0 : i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj,
     573                 :            :                          const struct drm_i915_gem_pwrite *args)
     574                 :            : {
     575         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(obj->base.dev);
     576                 :          0 :         struct i915_ggtt *ggtt = &i915->ggtt;
     577                 :          0 :         struct intel_runtime_pm *rpm = &i915->runtime_pm;
     578                 :          0 :         intel_wakeref_t wakeref;
     579                 :          0 :         struct drm_mm_node node;
     580                 :          0 :         struct dma_fence *fence;
     581                 :          0 :         struct i915_vma *vma;
     582                 :          0 :         u64 remain, offset;
     583                 :          0 :         void __user *user_data;
     584                 :          0 :         int ret;
     585                 :            : 
     586         [ #  # ]:          0 :         if (i915_gem_object_has_struct_page(obj)) {
     587                 :            :                 /*
     588                 :            :                  * Avoid waking the device up if we can fallback, as
     589                 :            :                  * waking/resuming is very slow (worst-case 10-100 ms
     590                 :            :                  * depending on PCI sleeps and our own resume time).
     591                 :            :                  * This easily dwarfs any performance advantage from
     592                 :            :                  * using the cache bypass of indirect GGTT access.
     593                 :            :                  */
     594                 :          0 :                 wakeref = intel_runtime_pm_get_if_in_use(rpm);
     595         [ #  # ]:          0 :                 if (!wakeref)
     596                 :            :                         return -EFAULT;
     597                 :            :         } else {
     598                 :            :                 /* No backing pages, no fallback, we must force GGTT access */
     599                 :          0 :                 wakeref = intel_runtime_pm_get(rpm);
     600                 :            :         }
     601                 :            : 
     602         [ #  # ]:          0 :         vma = ERR_PTR(-ENODEV);
     603         [ #  # ]:          0 :         if (!i915_gem_object_is_tiled(obj))
     604                 :          0 :                 vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
     605                 :            :                                                PIN_MAPPABLE |
     606                 :            :                                                PIN_NONBLOCK /* NOWARN */ |
     607                 :            :                                                PIN_NOEVICT);
     608         [ #  # ]:          0 :         if (!IS_ERR(vma)) {
     609                 :          0 :                 node.start = i915_ggtt_offset(vma);
     610                 :          0 :                 node.flags = 0;
     611                 :            :         } else {
     612                 :          0 :                 ret = insert_mappable_node(ggtt, &node, PAGE_SIZE);
     613         [ #  # ]:          0 :                 if (ret)
     614                 :          0 :                         goto out_rpm;
     615                 :          0 :                 GEM_BUG_ON(!drm_mm_node_allocated(&node));
     616                 :            :         }
     617                 :            : 
     618                 :          0 :         ret = i915_gem_object_lock_interruptible(obj);
     619         [ #  # ]:          0 :         if (ret)
     620                 :          0 :                 goto out_unpin;
     621                 :            : 
     622                 :          0 :         ret = i915_gem_object_set_to_gtt_domain(obj, true);
     623         [ #  # ]:          0 :         if (ret) {
     624                 :          0 :                 i915_gem_object_unlock(obj);
     625                 :          0 :                 goto out_unpin;
     626                 :            :         }
     627                 :            : 
     628                 :          0 :         fence = i915_gem_object_lock_fence(obj);
     629                 :          0 :         i915_gem_object_unlock(obj);
     630         [ #  # ]:          0 :         if (!fence) {
     631                 :          0 :                 ret = -ENOMEM;
     632                 :          0 :                 goto out_unpin;
     633                 :            :         }
     634                 :            : 
     635         [ #  # ]:          0 :         i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU);
     636                 :            : 
     637                 :          0 :         user_data = u64_to_user_ptr(args->data_ptr);
     638                 :          0 :         offset = args->offset;
     639                 :          0 :         remain = args->size;
     640         [ #  # ]:          0 :         while (remain) {
     641                 :            :                 /* Operation in this page
     642                 :            :                  *
     643                 :            :                  * page_base = page offset within aperture
     644                 :            :                  * page_offset = offset within page
     645                 :            :                  * page_length = bytes to copy for this page
     646                 :            :                  */
     647                 :          0 :                 u32 page_base = node.start;
     648                 :          0 :                 unsigned int page_offset = offset_in_page(offset);
     649                 :          0 :                 unsigned int page_length = PAGE_SIZE - page_offset;
     650                 :          0 :                 page_length = remain < page_length ? remain : page_length;
     651         [ #  # ]:          0 :                 if (drm_mm_node_allocated(&node)) {
     652                 :            :                         /* flush the write before we modify the GGTT */
     653                 :          0 :                         intel_gt_flush_ggtt_writes(ggtt->vm.gt);
     654                 :          0 :                         ggtt->vm.insert_page(&ggtt->vm,
     655                 :          0 :                                              i915_gem_object_get_dma_address(obj, offset >> PAGE_SHIFT),
     656                 :            :                                              node.start, I915_CACHE_NONE, 0);
     657                 :          0 :                         wmb(); /* flush modifications to the GGTT (insert_page) */
     658                 :            :                 } else {
     659                 :          0 :                         page_base += offset & PAGE_MASK;
     660                 :            :                 }
     661                 :            :                 /* If we get a fault while copying data, then (presumably) our
     662                 :            :                  * source page isn't available.  Return the error and we'll
     663                 :            :                  * retry in the slow path.
     664                 :            :                  * If the object is non-shmem backed, we retry again with the
     665                 :            :                  * path that handles page fault.
     666                 :            :                  */
     667         [ #  # ]:          0 :                 if (ggtt_write(&ggtt->iomap, page_base, page_offset,
     668                 :            :                                user_data, page_length)) {
     669                 :            :                         ret = -EFAULT;
     670                 :            :                         break;
     671                 :            :                 }
     672                 :            : 
     673                 :          0 :                 remain -= page_length;
     674                 :          0 :                 user_data += page_length;
     675                 :          0 :                 offset += page_length;
     676                 :            :         }
     677                 :            : 
     678                 :          0 :         intel_gt_flush_ggtt_writes(ggtt->vm.gt);
     679         [ #  # ]:          0 :         i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
     680                 :            : 
     681                 :          0 :         i915_gem_object_unlock_fence(obj, fence);
     682                 :          0 : out_unpin:
     683         [ #  # ]:          0 :         if (drm_mm_node_allocated(&node)) {
     684                 :          0 :                 ggtt->vm.clear_range(&ggtt->vm, node.start, node.size);
     685                 :          0 :                 remove_mappable_node(ggtt, &node);
     686                 :            :         } else {
     687                 :          0 :                 i915_vma_unpin(vma);
     688                 :            :         }
     689                 :          0 : out_rpm:
     690                 :          0 :         intel_runtime_pm_put(rpm, wakeref);
     691                 :          0 :         return ret;
     692                 :            : }
     693                 :            : 
     694                 :            : /* Per-page copy function for the shmem pwrite fastpath.
     695                 :            :  * Flushes invalid cachelines before writing to the target if
     696                 :            :  * needs_clflush_before is set and flushes out any written cachelines after
     697                 :            :  * writing if needs_clflush is set.
     698                 :            :  */
     699                 :            : static int
     700                 :          0 : shmem_pwrite(struct page *page, int offset, int len, char __user *user_data,
     701                 :            :              bool needs_clflush_before,
     702                 :            :              bool needs_clflush_after)
     703                 :            : {
     704                 :          0 :         char *vaddr;
     705                 :          0 :         int ret;
     706                 :            : 
     707                 :          0 :         vaddr = kmap(page);
     708                 :            : 
     709         [ #  # ]:          0 :         if (needs_clflush_before)
     710                 :          0 :                 drm_clflush_virt_range(vaddr + offset, len);
     711                 :            : 
     712                 :          0 :         ret = __copy_from_user(vaddr + offset, user_data, len);
     713         [ #  # ]:          0 :         if (!ret && needs_clflush_after)
     714                 :          0 :                 drm_clflush_virt_range(vaddr + offset, len);
     715                 :            : 
     716         [ #  # ]:          0 :         kunmap(page);
     717                 :            : 
     718         [ #  # ]:          0 :         return ret ? -EFAULT : 0;
     719                 :            : }
     720                 :            : 
     721                 :            : static int
     722                 :          0 : i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj,
     723                 :            :                       const struct drm_i915_gem_pwrite *args)
     724                 :            : {
     725                 :          0 :         unsigned int partial_cacheline_write;
     726                 :          0 :         unsigned int needs_clflush;
     727                 :          0 :         unsigned int offset, idx;
     728                 :          0 :         struct dma_fence *fence;
     729                 :          0 :         void __user *user_data;
     730                 :          0 :         u64 remain;
     731                 :          0 :         int ret;
     732                 :            : 
     733                 :          0 :         ret = i915_gem_object_prepare_write(obj, &needs_clflush);
     734         [ #  # ]:          0 :         if (ret)
     735                 :            :                 return ret;
     736                 :            : 
     737                 :          0 :         fence = i915_gem_object_lock_fence(obj);
     738                 :          0 :         i915_gem_object_finish_access(obj);
     739         [ #  # ]:          0 :         if (!fence)
     740                 :            :                 return -ENOMEM;
     741                 :            : 
     742                 :            :         /* If we don't overwrite a cacheline completely we need to be
     743                 :            :          * careful to have up-to-date data by first clflushing. Don't
     744                 :            :          * overcomplicate things and flush the entire patch.
     745                 :            :          */
     746                 :          0 :         partial_cacheline_write = 0;
     747         [ #  # ]:          0 :         if (needs_clflush & CLFLUSH_BEFORE)
     748                 :          0 :                 partial_cacheline_write = boot_cpu_data.x86_clflush_size - 1;
     749                 :            : 
     750                 :          0 :         user_data = u64_to_user_ptr(args->data_ptr);
     751                 :          0 :         remain = args->size;
     752                 :          0 :         offset = offset_in_page(args->offset);
     753         [ #  # ]:          0 :         for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
     754                 :          0 :                 struct page *page = i915_gem_object_get_page(obj, idx);
     755                 :          0 :                 unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
     756                 :            : 
     757                 :          0 :                 ret = shmem_pwrite(page, offset, length, user_data,
     758                 :          0 :                                    (offset | length) & partial_cacheline_write,
     759                 :          0 :                                    needs_clflush & CLFLUSH_AFTER);
     760         [ #  # ]:          0 :                 if (ret)
     761                 :            :                         break;
     762                 :            : 
     763                 :          0 :                 remain -= length;
     764                 :          0 :                 user_data += length;
     765                 :          0 :                 offset = 0;
     766                 :            :         }
     767                 :            : 
     768         [ #  # ]:          0 :         i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU);
     769                 :          0 :         i915_gem_object_unlock_fence(obj, fence);
     770                 :            : 
     771                 :          0 :         return ret;
     772                 :            : }
     773                 :            : 
     774                 :            : /**
     775                 :            :  * Writes data to the object referenced by handle.
     776                 :            :  * @dev: drm device
     777                 :            :  * @data: ioctl data blob
     778                 :            :  * @file: drm file
     779                 :            :  *
     780                 :            :  * On error, the contents of the buffer that were to be modified are undefined.
     781                 :            :  */
     782                 :            : int
     783                 :          0 : i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
     784                 :            :                       struct drm_file *file)
     785                 :            : {
     786                 :          0 :         struct drm_i915_gem_pwrite *args = data;
     787                 :          0 :         struct drm_i915_gem_object *obj;
     788                 :          0 :         int ret;
     789                 :            : 
     790         [ #  # ]:          0 :         if (args->size == 0)
     791                 :            :                 return 0;
     792                 :            : 
     793   [ #  #  #  # ]:          0 :         if (!access_ok(u64_to_user_ptr(args->data_ptr), args->size))
     794                 :            :                 return -EFAULT;
     795                 :            : 
     796                 :          0 :         obj = i915_gem_object_lookup(file, args->handle);
     797         [ #  # ]:          0 :         if (!obj)
     798                 :            :                 return -ENOENT;
     799                 :            : 
     800                 :            :         /* Bounds check destination. */
     801   [ #  #  #  # ]:          0 :         if (range_overflows_t(u64, args->offset, args->size, obj->base.size)) {
     802                 :          0 :                 ret = -EINVAL;
     803                 :          0 :                 goto err;
     804                 :            :         }
     805                 :            : 
     806                 :            :         /* Writes not allowed into this read-only object */
     807         [ #  # ]:          0 :         if (i915_gem_object_is_readonly(obj)) {
     808                 :          0 :                 ret = -EINVAL;
     809                 :          0 :                 goto err;
     810                 :            :         }
     811                 :            : 
     812                 :          0 :         trace_i915_gem_object_pwrite(obj, args->offset, args->size);
     813                 :            : 
     814                 :          0 :         ret = -ENODEV;
     815         [ #  # ]:          0 :         if (obj->ops->pwrite)
     816                 :          0 :                 ret = obj->ops->pwrite(obj, args);
     817         [ #  # ]:          0 :         if (ret != -ENODEV)
     818                 :          0 :                 goto err;
     819                 :            : 
     820                 :          0 :         ret = i915_gem_object_wait(obj,
     821                 :            :                                    I915_WAIT_INTERRUPTIBLE |
     822                 :            :                                    I915_WAIT_ALL,
     823                 :            :                                    MAX_SCHEDULE_TIMEOUT);
     824         [ #  # ]:          0 :         if (ret)
     825                 :          0 :                 goto err;
     826                 :            : 
     827                 :          0 :         ret = i915_gem_object_pin_pages(obj);
     828         [ #  # ]:          0 :         if (ret)
     829                 :          0 :                 goto err;
     830                 :            : 
     831                 :          0 :         ret = -EFAULT;
     832                 :            :         /* We can only do the GTT pwrite on untiled buffers, as otherwise
     833                 :            :          * it would end up going through the fenced access, and we'll get
     834                 :            :          * different detiling behavior between reading and writing.
     835                 :            :          * pread/pwrite currently are reading and writing from the CPU
     836                 :            :          * perspective, requiring manual detiling by the client.
     837                 :            :          */
     838   [ #  #  #  # ]:          0 :         if (!i915_gem_object_has_struct_page(obj) ||
     839                 :            :             cpu_write_needs_clflush(obj))
     840                 :            :                 /* Note that the gtt paths might fail with non-page-backed user
     841                 :            :                  * pointers (e.g. gtt mappings when moving data between
     842                 :            :                  * textures). Fallback to the shmem path in that case.
     843                 :            :                  */
     844                 :          0 :                 ret = i915_gem_gtt_pwrite_fast(obj, args);
     845                 :            : 
     846         [ #  # ]:          0 :         if (ret == -EFAULT || ret == -ENOSPC) {
     847         [ #  # ]:          0 :                 if (i915_gem_object_has_struct_page(obj))
     848                 :          0 :                         ret = i915_gem_shmem_pwrite(obj, args);
     849                 :            :                 else
     850                 :          0 :                         ret = i915_gem_phys_pwrite(obj, args, file);
     851                 :            :         }
     852                 :            : 
     853                 :          0 :         i915_gem_object_unpin_pages(obj);
     854                 :          0 : err:
     855                 :          0 :         i915_gem_object_put(obj);
     856                 :          0 :         return ret;
     857                 :            : }
     858                 :            : 
     859                 :            : /**
     860                 :            :  * Called when user space has done writes to this buffer
     861                 :            :  * @dev: drm device
     862                 :            :  * @data: ioctl data blob
     863                 :            :  * @file: drm file
     864                 :            :  */
     865                 :            : int
     866                 :          0 : i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
     867                 :            :                          struct drm_file *file)
     868                 :            : {
     869                 :          0 :         struct drm_i915_gem_sw_finish *args = data;
     870                 :          0 :         struct drm_i915_gem_object *obj;
     871                 :            : 
     872                 :          0 :         obj = i915_gem_object_lookup(file, args->handle);
     873         [ #  # ]:          0 :         if (!obj)
     874                 :            :                 return -ENOENT;
     875                 :            : 
     876                 :            :         /*
     877                 :            :          * Proxy objects are barred from CPU access, so there is no
     878                 :            :          * need to ban sw_finish as it is a nop.
     879                 :            :          */
     880                 :            : 
     881                 :            :         /* Pinned buffers may be scanout, so flush the cache */
     882                 :          0 :         i915_gem_object_flush_if_display(obj);
     883                 :          0 :         i915_gem_object_put(obj);
     884                 :            : 
     885                 :          0 :         return 0;
     886                 :            : }
     887                 :            : 
     888                 :          0 : void i915_gem_runtime_suspend(struct drm_i915_private *i915)
     889                 :            : {
     890                 :          0 :         struct drm_i915_gem_object *obj, *on;
     891                 :          0 :         int i;
     892                 :            : 
     893                 :            :         /*
     894                 :            :          * Only called during RPM suspend. All users of the userfault_list
     895                 :            :          * must be holding an RPM wakeref to ensure that this can not
     896                 :            :          * run concurrently with themselves (and use the struct_mutex for
     897                 :            :          * protection between themselves).
     898                 :            :          */
     899                 :            : 
     900         [ #  # ]:          0 :         list_for_each_entry_safe(obj, on,
     901                 :            :                                  &i915->ggtt.userfault_list, userfault_link)
     902                 :          0 :                 __i915_gem_object_release_mmap_gtt(obj);
     903                 :            : 
     904                 :            :         /*
     905                 :            :          * The fence will be lost when the device powers down. If any were
     906                 :            :          * in use by hardware (i.e. they are pinned), we should not be powering
     907                 :            :          * down! All other fences will be reacquired by the user upon waking.
     908                 :            :          */
     909         [ #  # ]:          0 :         for (i = 0; i < i915->ggtt.num_fences; i++) {
     910                 :          0 :                 struct i915_fence_reg *reg = &i915->ggtt.fence_regs[i];
     911                 :            : 
     912                 :            :                 /*
     913                 :            :                  * Ideally we want to assert that the fence register is not
     914                 :            :                  * live at this point (i.e. that no piece of code will be
     915                 :            :                  * trying to write through fence + GTT, as that both violates
     916                 :            :                  * our tracking of activity and associated locking/barriers,
     917                 :            :                  * but also is illegal given that the hw is powered down).
     918                 :            :                  *
     919                 :            :                  * Previously we used reg->pin_count as a "liveness" indicator.
     920                 :            :                  * That is not sufficient, and we need a more fine-grained
     921                 :            :                  * tool if we want to have a sanity check here.
     922                 :            :                  */
     923                 :            : 
     924         [ #  # ]:          0 :                 if (!reg->vma)
     925                 :          0 :                         continue;
     926                 :            : 
     927                 :          0 :                 GEM_BUG_ON(i915_vma_has_userfault(reg->vma));
     928                 :          0 :                 reg->dirty = true;
     929                 :            :         }
     930                 :          0 : }
     931                 :            : 
     932                 :            : struct i915_vma *
     933                 :          0 : i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
     934                 :            :                          const struct i915_ggtt_view *view,
     935                 :            :                          u64 size,
     936                 :            :                          u64 alignment,
     937                 :            :                          u64 flags)
     938                 :            : {
     939         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(obj->base.dev);
     940                 :          0 :         struct i915_ggtt *ggtt = &i915->ggtt;
     941                 :          0 :         struct i915_vma *vma;
     942                 :          0 :         int ret;
     943                 :            : 
     944         [ #  # ]:          0 :         if (i915_gem_object_never_bind_ggtt(obj))
     945                 :            :                 return ERR_PTR(-ENODEV);
     946                 :            : 
     947   [ #  #  #  # ]:          0 :         if (flags & PIN_MAPPABLE &&
     948         [ #  # ]:          0 :             (!view || view->type == I915_GGTT_VIEW_NORMAL)) {
     949                 :            :                 /*
     950                 :            :                  * If the required space is larger than the available
     951                 :            :                  * aperture, we will not able to find a slot for the
     952                 :            :                  * object and unbinding the object now will be in
     953                 :            :                  * vain. Worse, doing so may cause us to ping-pong
     954                 :            :                  * the object in and out of the Global GTT and
     955                 :            :                  * waste a lot of cycles under the mutex.
     956                 :            :                  */
     957         [ #  # ]:          0 :                 if (obj->base.size > ggtt->mappable_end)
     958                 :            :                         return ERR_PTR(-E2BIG);
     959                 :            : 
     960                 :            :                 /*
     961                 :            :                  * If NONBLOCK is set the caller is optimistically
     962                 :            :                  * trying to cache the full object within the mappable
     963                 :            :                  * aperture, and *must* have a fallback in place for
     964                 :            :                  * situations where we cannot bind the object. We
     965                 :            :                  * can be a little more lax here and use the fallback
     966                 :            :                  * more often to avoid costly migrations of ourselves
     967                 :            :                  * and other objects within the aperture.
     968                 :            :                  *
     969                 :            :                  * Half-the-aperture is used as a simple heuristic.
     970                 :            :                  * More interesting would to do search for a free
     971                 :            :                  * block prior to making the commitment to unbind.
     972                 :            :                  * That caters for the self-harm case, and with a
     973                 :            :                  * little more heuristics (e.g. NOFAULT, NOEVICT)
     974                 :            :                  * we could try to minimise harm to others.
     975                 :            :                  */
     976         [ #  # ]:          0 :                 if (flags & PIN_NONBLOCK &&
     977         [ #  # ]:          0 :                     obj->base.size > ggtt->mappable_end / 2)
     978                 :            :                         return ERR_PTR(-ENOSPC);
     979                 :            :         }
     980                 :            : 
     981                 :          0 :         vma = i915_vma_instance(obj, &ggtt->vm, view);
     982         [ #  # ]:          0 :         if (IS_ERR(vma))
     983                 :            :                 return vma;
     984                 :            : 
     985         [ #  # ]:          0 :         if (i915_vma_misplaced(vma, size, alignment, flags)) {
     986         [ #  # ]:          0 :                 if (flags & PIN_NONBLOCK) {
     987   [ #  #  #  # ]:          0 :                         if (i915_vma_is_pinned(vma) || i915_vma_is_active(vma))
     988                 :          0 :                                 return ERR_PTR(-ENOSPC);
     989                 :            : 
     990         [ #  # ]:          0 :                         if (flags & PIN_MAPPABLE &&
     991         [ #  # ]:          0 :                             vma->fence_size > ggtt->mappable_end / 2)
     992                 :            :                                 return ERR_PTR(-ENOSPC);
     993                 :            :                 }
     994                 :            : 
     995                 :          0 :                 ret = i915_vma_unbind(vma);
     996         [ #  # ]:          0 :                 if (ret)
     997                 :          0 :                         return ERR_PTR(ret);
     998                 :            :         }
     999                 :            : 
    1000   [ #  #  #  # ]:          0 :         if (vma->fence && !i915_gem_object_is_tiled(obj)) {
    1001                 :          0 :                 mutex_lock(&ggtt->vm.mutex);
    1002                 :          0 :                 ret = i915_vma_revoke_fence(vma);
    1003                 :          0 :                 mutex_unlock(&ggtt->vm.mutex);
    1004         [ #  # ]:          0 :                 if (ret)
    1005                 :          0 :                         return ERR_PTR(ret);
    1006                 :            :         }
    1007                 :            : 
    1008                 :          0 :         ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
    1009         [ #  # ]:          0 :         if (ret)
    1010                 :          0 :                 return ERR_PTR(ret);
    1011                 :            : 
    1012                 :            :         return vma;
    1013                 :            : }
    1014                 :            : 
    1015                 :            : int
    1016                 :          0 : i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
    1017                 :            :                        struct drm_file *file_priv)
    1018                 :            : {
    1019         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(dev);
    1020                 :          0 :         struct drm_i915_gem_madvise *args = data;
    1021                 :          0 :         struct drm_i915_gem_object *obj;
    1022                 :          0 :         int err;
    1023                 :            : 
    1024         [ #  # ]:          0 :         switch (args->madv) {
    1025                 :            :         case I915_MADV_DONTNEED:
    1026                 :            :         case I915_MADV_WILLNEED:
    1027                 :          0 :             break;
    1028                 :            :         default:
    1029                 :            :             return -EINVAL;
    1030                 :            :         }
    1031                 :            : 
    1032                 :          0 :         obj = i915_gem_object_lookup(file_priv, args->handle);
    1033         [ #  # ]:          0 :         if (!obj)
    1034                 :            :                 return -ENOENT;
    1035                 :            : 
    1036                 :          0 :         err = mutex_lock_interruptible(&obj->mm.lock);
    1037         [ #  # ]:          0 :         if (err)
    1038                 :          0 :                 goto out;
    1039                 :            : 
    1040   [ #  #  #  #  :          0 :         if (i915_gem_object_has_pages(obj) &&
                   #  # ]
    1041                 :          0 :             i915_gem_object_is_tiled(obj) &&
    1042         [ #  # ]:          0 :             i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
    1043         [ #  # ]:          0 :                 if (obj->mm.madv == I915_MADV_WILLNEED) {
    1044                 :          0 :                         GEM_BUG_ON(!obj->mm.quirked);
    1045                 :          0 :                         __i915_gem_object_unpin_pages(obj);
    1046                 :          0 :                         obj->mm.quirked = false;
    1047                 :            :                 }
    1048         [ #  # ]:          0 :                 if (args->madv == I915_MADV_WILLNEED) {
    1049                 :          0 :                         GEM_BUG_ON(obj->mm.quirked);
    1050                 :          0 :                         __i915_gem_object_pin_pages(obj);
    1051                 :          0 :                         obj->mm.quirked = true;
    1052                 :            :                 }
    1053                 :            :         }
    1054                 :            : 
    1055         [ #  # ]:          0 :         if (obj->mm.madv != __I915_MADV_PURGED)
    1056                 :          0 :                 obj->mm.madv = args->madv;
    1057                 :            : 
    1058   [ #  #  #  # ]:          0 :         if (i915_gem_object_has_pages(obj)) {
    1059                 :          0 :                 struct list_head *list;
    1060                 :            : 
    1061         [ #  # ]:          0 :                 if (i915_gem_object_is_shrinkable(obj)) {
    1062                 :          0 :                         unsigned long flags;
    1063                 :            : 
    1064                 :          0 :                         spin_lock_irqsave(&i915->mm.obj_lock, flags);
    1065                 :            : 
    1066         [ #  # ]:          0 :                         if (obj->mm.madv != I915_MADV_WILLNEED)
    1067                 :          0 :                                 list = &i915->mm.purge_list;
    1068                 :            :                         else
    1069                 :          0 :                                 list = &i915->mm.shrink_list;
    1070                 :          0 :                         list_move_tail(&obj->mm.link, list);
    1071                 :            : 
    1072                 :          0 :                         spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
    1073                 :            :                 }
    1074                 :            :         }
    1075                 :            : 
    1076                 :            :         /* if the object is no longer attached, discard its backing storage */
    1077   [ #  #  #  # ]:          0 :         if (obj->mm.madv == I915_MADV_DONTNEED &&
    1078                 :            :             !i915_gem_object_has_pages(obj))
    1079                 :          0 :                 i915_gem_object_truncate(obj);
    1080                 :            : 
    1081                 :          0 :         args->retained = obj->mm.madv != __I915_MADV_PURGED;
    1082                 :          0 :         mutex_unlock(&obj->mm.lock);
    1083                 :            : 
    1084                 :          0 : out:
    1085                 :          0 :         i915_gem_object_put(obj);
    1086                 :          0 :         return err;
    1087                 :            : }
    1088                 :            : 
    1089                 :          0 : int i915_gem_init(struct drm_i915_private *dev_priv)
    1090                 :            : {
    1091                 :          0 :         int ret;
    1092                 :            : 
    1093                 :            :         /* We need to fallback to 4K pages if host doesn't support huge gtt. */
    1094   [ #  #  #  # ]:          0 :         if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))
    1095                 :          0 :                 mkwrite_device_info(dev_priv)->page_sizes =
    1096                 :            :                         I915_GTT_PAGE_SIZE_4K;
    1097                 :            : 
    1098                 :          0 :         ret = i915_gem_init_userptr(dev_priv);
    1099         [ #  # ]:          0 :         if (ret)
    1100                 :            :                 return ret;
    1101                 :            : 
    1102         [ #  # ]:          0 :         intel_uc_fetch_firmwares(&dev_priv->gt.uc);
    1103                 :          0 :         intel_wopcm_init(&dev_priv->wopcm);
    1104                 :            : 
    1105                 :          0 :         ret = i915_init_ggtt(dev_priv);
    1106         [ #  # ]:          0 :         if (ret) {
    1107                 :          0 :                 GEM_BUG_ON(ret == -EIO);
    1108                 :          0 :                 goto err_unlock;
    1109                 :            :         }
    1110                 :            : 
    1111                 :            :         /*
    1112                 :            :          * Despite its name intel_init_clock_gating applies both display
    1113                 :            :          * clock gating workarounds; GT mmio workarounds and the occasional
    1114                 :            :          * GT power context workaround. Worse, sometimes it includes a context
    1115                 :            :          * register workaround which we need to apply before we record the
    1116                 :            :          * default HW state for all contexts.
    1117                 :            :          *
    1118                 :            :          * FIXME: break up the workarounds and apply them at the right time!
    1119                 :            :          */
    1120                 :          0 :         intel_init_clock_gating(dev_priv);
    1121                 :            : 
    1122                 :          0 :         ret = intel_gt_init(&dev_priv->gt);
    1123         [ #  # ]:          0 :         if (ret)
    1124                 :          0 :                 goto err_unlock;
    1125                 :            : 
    1126                 :            :         return 0;
    1127                 :            : 
    1128                 :            :         /*
    1129                 :            :          * Unwinding is complicated by that we want to handle -EIO to mean
    1130                 :            :          * disable GPU submission but keep KMS alive. We want to mark the
    1131                 :            :          * HW as irrevisibly wedged, but keep enough state around that the
    1132                 :            :          * driver doesn't explode during runtime.
    1133                 :            :          */
    1134                 :          0 : err_unlock:
    1135                 :          0 :         i915_gem_drain_workqueue(dev_priv);
    1136                 :            : 
    1137         [ #  # ]:          0 :         if (ret != -EIO) {
    1138         [ #  # ]:          0 :                 intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
    1139                 :          0 :                 i915_gem_cleanup_userptr(dev_priv);
    1140                 :            :         }
    1141                 :            : 
    1142         [ #  # ]:          0 :         if (ret == -EIO) {
    1143                 :            :                 /*
    1144                 :            :                  * Allow engines or uC initialisation to fail by marking the GPU
    1145                 :            :                  * as wedged. But we only want to do this when the GPU is angry,
    1146                 :            :                  * for all other failure, such as an allocation failure, bail.
    1147                 :            :                  */
    1148         [ #  # ]:          0 :                 if (!intel_gt_is_wedged(&dev_priv->gt)) {
    1149                 :          0 :                         i915_probe_error(dev_priv,
    1150                 :            :                                          "Failed to initialize GPU, declaring it wedged!\n");
    1151                 :          0 :                         intel_gt_set_wedged(&dev_priv->gt);
    1152                 :            :                 }
    1153                 :            : 
    1154                 :            :                 /* Minimal basic recovery for KMS */
    1155                 :          0 :                 ret = i915_ggtt_enable_hw(dev_priv);
    1156                 :          0 :                 i915_gem_restore_gtt_mappings(dev_priv);
    1157                 :          0 :                 i915_gem_restore_fences(&dev_priv->ggtt);
    1158                 :          0 :                 intel_init_clock_gating(dev_priv);
    1159                 :            :         }
    1160                 :            : 
    1161                 :          0 :         i915_gem_drain_freed_objects(dev_priv);
    1162                 :          0 :         return ret;
    1163                 :            : }
    1164                 :            : 
    1165                 :          0 : void i915_gem_driver_register(struct drm_i915_private *i915)
    1166                 :            : {
    1167                 :          0 :         i915_gem_driver_register__shrinker(i915);
    1168                 :            : 
    1169                 :          0 :         intel_engines_driver_register(i915);
    1170                 :          0 : }
    1171                 :            : 
    1172                 :          0 : void i915_gem_driver_unregister(struct drm_i915_private *i915)
    1173                 :            : {
    1174                 :          0 :         i915_gem_driver_unregister__shrinker(i915);
    1175                 :          0 : }
    1176                 :            : 
    1177                 :          0 : void i915_gem_driver_remove(struct drm_i915_private *dev_priv)
    1178                 :            : {
    1179                 :          0 :         intel_wakeref_auto_fini(&dev_priv->ggtt.userfault_wakeref);
    1180                 :            : 
    1181                 :          0 :         i915_gem_suspend_late(dev_priv);
    1182                 :          0 :         intel_gt_driver_remove(&dev_priv->gt);
    1183                 :          0 :         dev_priv->uabi_engines = RB_ROOT;
    1184                 :            : 
    1185                 :            :         /* Flush any outstanding unpin_work. */
    1186                 :          0 :         i915_gem_drain_workqueue(dev_priv);
    1187                 :            : 
    1188                 :          0 :         i915_gem_drain_freed_objects(dev_priv);
    1189                 :          0 : }
    1190                 :            : 
    1191                 :          0 : void i915_gem_driver_release(struct drm_i915_private *dev_priv)
    1192                 :            : {
    1193                 :          0 :         i915_gem_driver_release__contexts(dev_priv);
    1194                 :            : 
    1195                 :          0 :         intel_gt_driver_release(&dev_priv->gt);
    1196                 :            : 
    1197                 :          0 :         intel_wa_list_free(&dev_priv->gt_wa_list);
    1198                 :            : 
    1199         [ #  # ]:          0 :         intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
    1200                 :          0 :         i915_gem_cleanup_userptr(dev_priv);
    1201                 :            : 
    1202                 :          0 :         i915_gem_drain_freed_objects(dev_priv);
    1203                 :            : 
    1204         [ #  # ]:          0 :         WARN_ON(!list_empty(&dev_priv->gem.contexts.list));
    1205                 :          0 : }
    1206                 :            : 
    1207                 :          0 : static void i915_gem_init__mm(struct drm_i915_private *i915)
    1208                 :            : {
    1209                 :          0 :         spin_lock_init(&i915->mm.obj_lock);
    1210                 :            : 
    1211                 :          0 :         init_llist_head(&i915->mm.free_list);
    1212                 :            : 
    1213                 :          0 :         INIT_LIST_HEAD(&i915->mm.purge_list);
    1214                 :          0 :         INIT_LIST_HEAD(&i915->mm.shrink_list);
    1215                 :            : 
    1216                 :          0 :         i915_gem_init__objects(i915);
    1217                 :            : }
    1218                 :            : 
    1219                 :          0 : void i915_gem_init_early(struct drm_i915_private *dev_priv)
    1220                 :            : {
    1221                 :          0 :         i915_gem_init__mm(dev_priv);
    1222                 :          0 :         i915_gem_init__contexts(dev_priv);
    1223                 :            : 
    1224                 :          0 :         spin_lock_init(&dev_priv->fb_tracking.lock);
    1225                 :          0 : }
    1226                 :            : 
    1227                 :          0 : void i915_gem_cleanup_early(struct drm_i915_private *dev_priv)
    1228                 :            : {
    1229                 :          0 :         i915_gem_drain_freed_objects(dev_priv);
    1230                 :          0 :         GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
    1231                 :          0 :         GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
    1232         [ #  # ]:          0 :         WARN_ON(dev_priv->mm.shrink_count);
    1233                 :          0 : }
    1234                 :            : 
    1235                 :          0 : int i915_gem_freeze(struct drm_i915_private *dev_priv)
    1236                 :            : {
    1237                 :            :         /* Discard all purgeable objects, let userspace recover those as
    1238                 :            :          * required after resuming.
    1239                 :            :          */
    1240                 :          0 :         i915_gem_shrink_all(dev_priv);
    1241                 :            : 
    1242                 :          0 :         return 0;
    1243                 :            : }
    1244                 :            : 
    1245                 :          0 : int i915_gem_freeze_late(struct drm_i915_private *i915)
    1246                 :            : {
    1247                 :          0 :         struct drm_i915_gem_object *obj;
    1248                 :          0 :         intel_wakeref_t wakeref;
    1249                 :            : 
    1250                 :            :         /*
    1251                 :            :          * Called just before we write the hibernation image.
    1252                 :            :          *
    1253                 :            :          * We need to update the domain tracking to reflect that the CPU
    1254                 :            :          * will be accessing all the pages to create and restore from the
    1255                 :            :          * hibernation, and so upon restoration those pages will be in the
    1256                 :            :          * CPU domain.
    1257                 :            :          *
    1258                 :            :          * To make sure the hibernation image contains the latest state,
    1259                 :            :          * we update that state just before writing out the image.
    1260                 :            :          *
    1261                 :            :          * To try and reduce the hibernation image, we manually shrink
    1262                 :            :          * the objects as well, see i915_gem_freeze()
    1263                 :            :          */
    1264                 :            : 
    1265                 :          0 :         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
    1266                 :            : 
    1267                 :          0 :         i915_gem_shrink(i915, -1UL, NULL, ~0);
    1268                 :          0 :         i915_gem_drain_freed_objects(i915);
    1269                 :            : 
    1270         [ #  # ]:          0 :         list_for_each_entry(obj, &i915->mm.shrink_list, mm.link) {
    1271                 :          0 :                 i915_gem_object_lock(obj);
    1272         [ #  # ]:          0 :                 WARN_ON(i915_gem_object_set_to_cpu_domain(obj, true));
    1273                 :          0 :                 i915_gem_object_unlock(obj);
    1274                 :            :         }
    1275                 :            : 
    1276                 :          0 :         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
    1277                 :            : 
    1278                 :          0 :         return 0;
    1279                 :            : }
    1280                 :            : 
    1281                 :          0 : void i915_gem_release(struct drm_device *dev, struct drm_file *file)
    1282                 :            : {
    1283                 :          0 :         struct drm_i915_file_private *file_priv = file->driver_priv;
    1284                 :          0 :         struct i915_request *request;
    1285                 :            : 
    1286                 :            :         /* Clean up our request list when the client is going away, so that
    1287                 :            :          * later retire_requests won't dereference our soon-to-be-gone
    1288                 :            :          * file_priv.
    1289                 :            :          */
    1290                 :          0 :         spin_lock(&file_priv->mm.lock);
    1291         [ #  # ]:          0 :         list_for_each_entry(request, &file_priv->mm.request_list, client_link)
    1292                 :          0 :                 request->file_priv = NULL;
    1293                 :          0 :         spin_unlock(&file_priv->mm.lock);
    1294                 :          0 : }
    1295                 :            : 
    1296                 :          0 : int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file)
    1297                 :            : {
    1298                 :          0 :         struct drm_i915_file_private *file_priv;
    1299                 :          0 :         int ret;
    1300                 :            : 
    1301                 :          0 :         DRM_DEBUG("\n");
    1302                 :            : 
    1303                 :          0 :         file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
    1304         [ #  # ]:          0 :         if (!file_priv)
    1305                 :            :                 return -ENOMEM;
    1306                 :            : 
    1307                 :          0 :         file->driver_priv = file_priv;
    1308                 :          0 :         file_priv->dev_priv = i915;
    1309                 :          0 :         file_priv->file = file;
    1310                 :            : 
    1311                 :          0 :         spin_lock_init(&file_priv->mm.lock);
    1312                 :          0 :         INIT_LIST_HEAD(&file_priv->mm.request_list);
    1313                 :            : 
    1314                 :          0 :         file_priv->bsd_engine = -1;
    1315                 :          0 :         file_priv->hang_timestamp = jiffies;
    1316                 :            : 
    1317                 :          0 :         ret = i915_gem_context_open(i915, file);
    1318         [ #  # ]:          0 :         if (ret)
    1319                 :          0 :                 kfree(file_priv);
    1320                 :            : 
    1321                 :            :         return ret;
    1322                 :            : }
    1323                 :            : 
    1324                 :            : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
    1325                 :            : #include "selftests/mock_gem_device.c"
    1326                 :            : #include "selftests/i915_gem.c"
    1327                 :            : #endif

Generated by: LCOV version 1.14