@@ -35,6 +35,8 @@
#include <drm/ttm/ttm_bo_driver.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/drm_vma_manager.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
#include <linux/mm.h>
#include <linux/pfn_t.h>
#include <linux/rbtree.h>
@@ -420,23 +422,59 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
}
EXPORT_SYMBOL(ttm_bo_vm_fault_reserved);
+vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf)
+{
+ struct vm_area_struct *vma = vmf->vma;
+ struct ttm_buffer_object *bo = vma->vm_private_data;
+ struct drm_file *file = NULL;
+ struct page *dummy_page = NULL;
+
+ /* We are faulting on imported BO from dma_buf */
+ if (bo->base.dma_buf && bo->base.import_attach) {
+ dummy_page = bo->base.dummy_page;
+ /* We are faulting on local BO */
+ } else {
+ file = vma->vm_file->private_data;
+ dummy_page = file->dummy_page;
+ }
+
+ /* Let do_fault complete the PTE install e.t.c using vmf->page */
+ get_page(dummy_page);
+ vmf->page = dummy_page;
+
+ return 0;
+}
+
vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
pgprot_t prot;
struct ttm_buffer_object *bo = vma->vm_private_data;
vm_fault_t ret;
+ int idx;
+ struct drm_device *ddev = bo->base.dev;
- ret = ttm_bo_vm_reserve(bo, vmf);
- if (ret)
- return ret;
- prot = vma->vm_page_prot;
- ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
- if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
- return ret;
+ if (!drm_dev_enter(ddev, &idx)) {
+ ret = ttm_bo_vm_dummy_page(vmf);
+ if (ret)
+ return ret;
+ } else {
+ ret = ttm_bo_vm_reserve(bo, vmf);
+ if (ret)
+ goto exit;
- dma_resv_unlock(bo->base.resv);
+ prot = vma->vm_page_prot;
+
+ ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
+ if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
+ goto exit;
+
+ dma_resv_unlock(bo->base.resv);
+
+exit:
+ drm_dev_exit(idx);
+ }
return ret;
}
On device removal reroute all CPU mappings to dummy page per drm_file instance or imported GEM object. v3: Remove loop to find DRM file and instead access it by vma->vm_file->private_data. Move dummy page installation into a separate function. Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 54 +++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-)