Quoting Matthew Auld (2019-08-09 23:26:38)
-void __i915_gem_object_release_mmap(struct drm_i915_gem_object *obj) +static vm_fault_t i915_gem_fault_cpu(struct vm_fault *vmf) +{
struct vm_area_struct *area = vmf->vma;
struct i915_mmap_offset *priv = area->vm_private_data;
struct drm_i915_gem_object *obj = priv->obj;
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
vm_fault_t vmf_ret;
unsigned long size = area->vm_end - area->vm_start;
bool write = area->vm_flags & VM_WRITE;
int i, ret;
/* Sanity check that we allow writing into this object */
if (i915_gem_object_is_readonly(obj) && write)
return VM_FAULT_SIGBUS;
ret = i915_gem_object_pin_pages(obj);
if (err) return i915_error_to_vmf_fault(err);
goto err;
for (i = 0; i < size >> PAGE_SHIFT; i++) {
struct page *page = i915_gem_object_get_page(obj, i);
vmf_ret = vmf_insert_pfn(area,
(unsigned long)area->vm_start + i * PAGE_SIZE,
page_to_pfn(page));
if (vmf_ret & VM_FAULT_ERROR) {
ret = vm_fault_to_errno(vmf_ret, 0);
break;
}
}
i915_gem_object_unpin_pages(obj);
return vmf_ret;