summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérôme Glisse <jglisse@redhat.com>2018-07-25 11:46:41 -0400
committerJérôme Glisse <jglisse@redhat.com>2019-01-29 10:34:59 -0500
commite31fdd7e818781b7b7c32ec68317080243e23b22 (patch)
tree1219e2259275f298d6d299788a4ecc4ecd79721a
parent6a7f254c1f1dc2f1fb83a27608532e41d9981cc5 (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.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_svm.c51
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_svm.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c6
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);