aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-02-08 05:08:35 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-02-10 14:17:16 -0500
commitcc325d1913475655b81c0417ba04c84f168ac78c (patch)
tree6dcc586983e753988a4b2713678f78bbb49ded6e
parent04db4caf5c836c211977a54c9218f2cdee14897f (diff)
drm/amdgpu: check userptrs mm earlier
Instead of when we try to bind it check the usermm when we try to use it in the IOCTLs. Signed-off-by: Christian König <christian.koenig@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c9
7 files changed, 27 insertions, 15 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 4a6e87857875..a783c684b49b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2364,7 +2364,7 @@ void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain);
2364bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); 2364bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
2365int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, 2365int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
2366 uint32_t flags); 2366 uint32_t flags);
2367bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); 2367struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);
2368bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, 2368bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
2369 unsigned long end); 2369 unsigned long end);
2370bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); 2370bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
index c4341dd4b6a4..90d6fc1618aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
@@ -93,6 +93,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
93 93
94 bool has_userptr = false; 94 bool has_userptr = false;
95 unsigned i; 95 unsigned i;
96 int r;
96 97
97 array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry)); 98 array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry));
98 if (!array) 99 if (!array)
@@ -102,17 +103,26 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
102 for (i = 0; i < num_entries; ++i) { 103 for (i = 0; i < num_entries; ++i) {
103 struct amdgpu_bo_list_entry *entry = &array[i]; 104 struct amdgpu_bo_list_entry *entry = &array[i];
104 struct drm_gem_object *gobj; 105 struct drm_gem_object *gobj;
106 struct mm_struct *usermm;
105 107
106 gobj = drm_gem_object_lookup(adev->ddev, filp, info[i].bo_handle); 108 gobj = drm_gem_object_lookup(adev->ddev, filp, info[i].bo_handle);
107 if (!gobj) 109 if (!gobj) {
110 r = -ENOENT;
108 goto error_free; 111 goto error_free;
112 }
109 113
110 entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); 114 entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
111 drm_gem_object_unreference_unlocked(gobj); 115 drm_gem_object_unreference_unlocked(gobj);
112 entry->priority = min(info[i].bo_priority, 116 entry->priority = min(info[i].bo_priority,
113 AMDGPU_BO_LIST_MAX_PRIORITY); 117 AMDGPU_BO_LIST_MAX_PRIORITY);
114 if (amdgpu_ttm_tt_has_userptr(entry->robj->tbo.ttm)) 118 usermm = amdgpu_ttm_tt_get_usermm(entry->robj->tbo.ttm);
119 if (usermm) {
120 if (usermm != current->mm) {
121 r = -EPERM;
122 goto error_free;
123 }
115 has_userptr = true; 124 has_userptr = true;
125 }
116 entry->tv.bo = &entry->robj->tbo; 126 entry->tv.bo = &entry->robj->tbo;
117 entry->tv.shared = true; 127 entry->tv.shared = true;
118 128
@@ -142,7 +152,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
142 152
143error_free: 153error_free:
144 drm_free_large(array); 154 drm_free_large(array);
145 return -ENOENT; 155 return r;
146} 156}
147 157
148struct amdgpu_bo_list * 158struct amdgpu_bo_list *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index a795af3ab0ad..e7e384264202 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -101,7 +101,7 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
101 p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); 101 p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
102 p->uf.offset = fence_data->offset; 102 p->uf.offset = fence_data->offset;
103 103
104 if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) { 104 if (amdgpu_ttm_tt_get_usermm(p->uf.bo->tbo.ttm)) {
105 drm_gem_object_unreference_unlocked(gobj); 105 drm_gem_object_unreference_unlocked(gobj);
106 return -EINVAL; 106 return -EINVAL;
107 } 107 }
@@ -296,8 +296,13 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
296 296
297 list_for_each_entry(lobj, validated, tv.head) { 297 list_for_each_entry(lobj, validated, tv.head) {
298 struct amdgpu_bo *bo = lobj->robj; 298 struct amdgpu_bo *bo = lobj->robj;
299 struct mm_struct *usermm;
299 uint32_t domain; 300 uint32_t domain;
300 301
302 usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
303 if (usermm && usermm != current->mm)
304 return -EPERM;
305
301 if (bo->pin_count) 306 if (bo->pin_count)
302 continue; 307 continue;
303 308
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 84e850f81f39..b1a611e79c94 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -310,7 +310,7 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,
310 return -ENOENT; 310 return -ENOENT;
311 } 311 }
312 robj = gem_to_amdgpu_bo(gobj); 312 robj = gem_to_amdgpu_bo(gobj);
313 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) || 313 if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||
314 (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { 314 (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) {
315 drm_gem_object_unreference_unlocked(gobj); 315 drm_gem_object_unreference_unlocked(gobj);
316 return -EPERM; 316 return -EPERM;
@@ -638,7 +638,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
638 break; 638 break;
639 } 639 }
640 case AMDGPU_GEM_OP_SET_PLACEMENT: 640 case AMDGPU_GEM_OP_SET_PLACEMENT:
641 if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) { 641 if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm)) {
642 r = -EPERM; 642 r = -EPERM;
643 amdgpu_bo_unreserve(robj); 643 amdgpu_bo_unreserve(robj);
644 break; 644 break;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 8c1fc1f56342..b74084ce734f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -370,7 +370,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
370 int r, i; 370 int r, i;
371 unsigned fpfn, lpfn; 371 unsigned fpfn, lpfn;
372 372
373 if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) 373 if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
374 return -EPERM; 374 return -EPERM;
375 375
376 if (WARN_ON_ONCE(min_offset > max_offset)) 376 if (WARN_ON_ONCE(min_offset > max_offset))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
index 59f735a933a9..a0bdb0e45c0f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
@@ -121,7 +121,7 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev,
121{ 121{
122 struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); 122 struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj);
123 123
124 if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) 124 if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm))
125 return ERR_PTR(-EPERM); 125 return ERR_PTR(-EPERM);
126 126
127 return drm_gem_prime_export(dev, gobj, flags); 127 return drm_gem_prime_export(dev, gobj, flags);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 100bfd4a0707..cdb393db11a5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -499,9 +499,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
499 enum dma_data_direction direction = write ? 499 enum dma_data_direction direction = write ?
500 DMA_BIDIRECTIONAL : DMA_TO_DEVICE; 500 DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
501 501
502 if (current->mm != gtt->usermm)
503 return -EPERM;
504
505 if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { 502 if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
506 /* check that we only pin down anonymous memory 503 /* check that we only pin down anonymous memory
507 to prevent problems with writeback */ 504 to prevent problems with writeback */
@@ -773,14 +770,14 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
773 return 0; 770 return 0;
774} 771}
775 772
776bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm) 773struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)
777{ 774{
778 struct amdgpu_ttm_tt *gtt = (void *)ttm; 775 struct amdgpu_ttm_tt *gtt = (void *)ttm;
779 776
780 if (gtt == NULL) 777 if (gtt == NULL)
781 return false; 778 return NULL;
782 779
783 return !!gtt->userptr; 780 return gtt->usermm;
784} 781}
785 782
786bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, 783bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,