diff options
author | Christian König <christian.koenig@amd.com> | 2016-02-08 05:08:35 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-10 14:17:16 -0500 |
commit | cc325d1913475655b81c0417ba04c84f168ac78c (patch) | |
tree | 6dcc586983e753988a4b2713678f78bbb49ded6e | |
parent | 04db4caf5c836c211977a54c9218f2cdee14897f (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.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 9 |
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); | |||
2364 | bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); | 2364 | bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); |
2365 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | 2365 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, |
2366 | uint32_t flags); | 2366 | uint32_t flags); |
2367 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); | 2367 | struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm); |
2368 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | 2368 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, |
2369 | unsigned long end); | 2369 | unsigned long end); |
2370 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); | 2370 | bool 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 | ||
143 | error_free: | 153 | error_free: |
144 | drm_free_large(array); | 154 | drm_free_large(array); |
145 | return -ENOENT; | 155 | return r; |
146 | } | 156 | } |
147 | 157 | ||
148 | struct amdgpu_bo_list * | 158 | struct 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 | ||
776 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm) | 773 | struct 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 | ||
786 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | 783 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, |