diff options
author | Jérôme Glisse <jglisse@redhat.com> | 2018-07-25 11:46:41 -0400 |
---|---|---|
committer | Jérôme Glisse <jglisse@redhat.com> | 2019-01-29 10:34:59 -0500 |
commit | e31fdd7e818781b7b7c32ec68317080243e23b22 (patch) | |
tree | 1219e2259275f298d6d299788a4ecc4ecd79721a | |
parent | 6a7f254c1f1dc2f1fb83a27608532e41d9981cc5 (diff) |
gpu/nouveau/svm: have reserved vma comes as a special mmap of device file
Enforce the reserved area to be the result of mmap on the device file.
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_svm.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_svm.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_ttm.c | 6 |
4 files changed, 61 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index abebb91f6764..2d8bed0946bc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -61,6 +61,7 @@ struct nouveau_channel; struct platform_device; #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) +#define TTM_FILE_PAGE_OFFSET (0x200000000ULL >> PAGE_SHIFT) #include "nouveau_fence.h" #include "nouveau_bios.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index 183b94511388..7f9e9404a226 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -35,6 +35,8 @@ #include <linux/sort.h> #include <linux/hmm.h> +static const struct vm_operations_struct nvkm_svm_reserved_vma_ops; + struct nouveau_svm { struct nouveau_drm *drm; struct mutex mutex; @@ -220,6 +222,7 @@ nouveau_svmm_init(struct drm_device *dev, void *data, struct nouveau_vmm *vmm = &cli->vmm; struct nouveau_svmm *svmm; struct drm_nouveau_svm_init *args = data; + struct vm_area_struct *vma; int ret = 0; /*XXX: Hack to replace per-client GPU address-space with one that @@ -249,6 +252,15 @@ nouveau_svmm_init(struct drm_device *dev, void *data, /* Enable HMM mirroring of CPU address-space to VMM. */ svmm->mm = get_task_mm(current); down_write(&svmm->mm->mmap_sem); + + vma = find_vma(svmm->mm, args->unmanaged_addr); + if (vma == NULL || vma->vm_ops != &nvkm_svm_reserved_vma_ops || + (svmm->unmanaged.limit > vma->vm_end)) { + up_write(&svmm->mm->mmap_sem); + ret = -EINVAL; + goto done; + } + svmm->mirror.ops = &nouveau_svmm; ret = hmm_mirror_register(&svmm->mirror, svmm->mm); up_write(&svmm->mm->mmap_sem); @@ -769,3 +781,42 @@ nouveau_svm_init(struct nouveau_drm *drm) INIT_LIST_HEAD(&drm->svm->inst); } } + +static int +nvkm_svm_reserved_vma_fault(struct vm_fault *vmf) +{ + return VM_FAULT_SIGBUS; +} + +static void +nvkm_svm_reserved_vma_open(struct vm_area_struct *vma) +{ +} + +static void +nvkm_svm_reserved_vma_close(struct vm_area_struct *vma) +{ +} + +static int +nvkm_svm_reserved_vma_access(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write) +{ + return -EIO; +} + +static const struct vm_operations_struct nvkm_svm_reserved_vma_ops = { + .access = nvkm_svm_reserved_vma_access, + .close = nvkm_svm_reserved_vma_close, + .fault = nvkm_svm_reserved_vma_fault, + .open = nvkm_svm_reserved_vma_open, +}; + +int +nvkm_svm_mmap_reserved(struct vm_area_struct *vma) +{ + vma->vm_ops = &nvkm_svm_reserved_vma_ops; + vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY; + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.h b/drivers/gpu/drm/nouveau/nouveau_svm.h index b43d94b98127..06504dd993bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.h +++ b/drivers/gpu/drm/nouveau/nouveau_svm.h @@ -16,4 +16,8 @@ int nouveau_svmm_init(struct drm_device *, void *, struct drm_file *); void nouveau_svmm_fini(struct nouveau_svmm **); int nouveau_svmm_join(struct nouveau_svmm *, u64 inst); void nouveau_svmm_part(struct nouveau_svmm *, u64 inst); + +struct vm_area_struct; + +int nvkm_svm_mmap_reserved(struct vm_area_struct *vma); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 1543c2f8d3d3..152e96a077fc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -26,6 +26,7 @@ #include "nouveau_gem.h" #include "nouveau_mem.h" #include "nouveau_ttm.h" +#include "nouveau_svm.h" #include <drm/drm_legacy.h> @@ -171,6 +172,9 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) return drm_legacy_mmap(filp, vma); + if (unlikely(vma->vm_pgoff < TTM_FILE_PAGE_OFFSET)) + return nvkm_svm_mmap_reserved(vma); + return ttm_bo_mmap(filp, vma, &drm->ttm.bdev); } @@ -239,7 +243,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) ret = ttm_bo_device_init(&drm->ttm.bdev, &nouveau_bo_driver, dev->anon_inode->i_mapping, - DRM_FILE_PAGE_OFFSET, + TTM_FILE_PAGE_OFFSET, drm->client.mmu.dmabits <= 32 ? true : false); if (ret) { NV_ERROR(drm, "error initialising bo driver, %d\n", ret); |