• Daniel Vetter's avatar
    drm/i915: rewrite shmem_pwrite_slow to use copy_from_user · 8c59967c
    Daniel Vetter authored
    ... instead of get_user_pages, because that fails on non page-backed
    user addresses like e.g. a gtt mapping of a bo.
    
    To get there essentially copy the vfs read path into pagecache. We
    can't call that right away because we have to take care of bit17
    swizzling. To not deadlock with our own pagefault handler we need
    to completely drop struct_mutex, reducing the atomicty-guarantees
    of our userspace abi. Implications for racing with other gem ioctl:
    
    - execbuf, pwrite, pread: Due to -EFAULT fallback to slow paths there's
      already the risk of the pwrite call not being atomic, no degration.
    - read/write access to mmaps: already fully racy, no degration.
    - set_tiling: Calling set_tiling while reading/writing is already
      pretty much undefined, now it just got a bit worse. set_tiling is
      only called by libdrm on unused/new bos, so no problem.
    - set_domain: When changing to the gtt domain while copying (without any
      read/write access, e.g. for synchronization), we might leave unflushed
      data in the cpu caches. The clflush_object at the end of pwrite_slow
      takes care of this problem.
    - truncating of purgeable objects: the shmem_read_mapping_page call could
      reinstate backing storage for truncated objects. The check at the end
      of pwrite_slow takes care of this.
    
    v2:
    - add missing intel_gtt_chipset_flush
    - add __ to copy_from_user_swizzled as suggest by Chris Wilson.
    
    v3: Fixup bit17 swizzling, it swizzled the wrong pages.
    Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
    8c59967c
i915_gem.c 106 KB