diff options
Diffstat (limited to 'linux-core/drm_vm.c')
-rw-r--r-- | linux-core/drm_vm.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 5afa9800..4a41e761 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -746,6 +746,30 @@ struct page *drm_bo_vm_fault(struct vm_area_struct *vma, mutex_lock(&bo->mutex); + /* + * If buffer happens to be in a non-mappable location, + * move it to a mappable. + */ + + if (!(bo->mem.flags & DRM_BO_FLAG_MAPPABLE)) { + uint32_t mask_save = bo->mem.mask; + uint32_t new_mask = bo->mem.mask | + DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_FORCE_MAPPABLE; + + err = drm_bo_move_buffer(bo, new_mask, 0, 0); + bo->mem.mask = mask_save; + + if (!err) + err = drm_bo_wait(bo, 0, 0, 0); + + if (err) { + data->type = (err == -EAGAIN) ? + VM_FAULT_MINOR : VM_FAULT_SIGBUS; + goto out_unlock; + } + } + if (address > vma->vm_end) { data->type = VM_FAULT_SIGBUS; goto out_unlock; |