aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/radeon.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c68
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c145
-rw-r--r--drivers/gpu/drm/radeon/radeon_vm.c3
-rw-r--r--include/uapi/drm/radeon_drm.h16
10 files changed, 279 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9e1732eb402c..6f38a23a5810 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2138,6 +2138,8 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
2138 struct drm_file *filp); 2138 struct drm_file *filp);
2139int radeon_gem_create_ioctl(struct drm_device *dev, void *data, 2139int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
2140 struct drm_file *filp); 2140 struct drm_file *filp);
2141int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
2142 struct drm_file *filp);
2141int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, 2143int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
2142 struct drm_file *file_priv); 2144 struct drm_file *file_priv);
2143int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, 2145int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
@@ -2871,6 +2873,10 @@ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enabl
2871extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); 2873extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
2872extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); 2874extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
2873extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); 2875extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
2876extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
2877 uint32_t flags);
2878extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm);
2879extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm);
2874extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); 2880extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base);
2875extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); 2881extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc);
2876extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); 2882extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index ee712c199b25..1321491cf499 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -78,7 +78,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
78 struct radeon_cs_chunk *chunk; 78 struct radeon_cs_chunk *chunk;
79 struct radeon_cs_buckets buckets; 79 struct radeon_cs_buckets buckets;
80 unsigned i, j; 80 unsigned i, j;
81 bool duplicate; 81 bool duplicate, need_mmap_lock = false;
82 int r;
82 83
83 if (p->chunk_relocs_idx == -1) { 84 if (p->chunk_relocs_idx == -1) {
84 return 0; 85 return 0;
@@ -164,6 +165,19 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
164 p->relocs[i].allowed_domains = domain; 165 p->relocs[i].allowed_domains = domain;
165 } 166 }
166 167
168 if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
169 uint32_t domain = p->relocs[i].prefered_domains;
170 if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
171 DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
172 "allowed for userptr BOs\n");
173 return -EINVAL;
174 }
175 need_mmap_lock = true;
176 domain = RADEON_GEM_DOMAIN_GTT;
177 p->relocs[i].prefered_domains = domain;
178 p->relocs[i].allowed_domains = domain;
179 }
180
167 p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; 181 p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
168 p->relocs[i].handle = r->handle; 182 p->relocs[i].handle = r->handle;
169 183
@@ -176,8 +190,15 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
176 if (p->cs_flags & RADEON_CS_USE_VM) 190 if (p->cs_flags & RADEON_CS_USE_VM)
177 p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, 191 p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
178 &p->validated); 192 &p->validated);
193 if (need_mmap_lock)
194 down_read(&current->mm->mmap_sem);
195
196 r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
179 197
180 return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring); 198 if (need_mmap_lock)
199 up_read(&current->mm->mmap_sem);
200
201 return r;
181} 202}
182 203
183static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority) 204static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index a773830c6c40..5b18af926527 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -114,6 +114,9 @@ int radeon_gem_object_open(struct drm_gem_object *obj,
114 struct drm_file *file_priv); 114 struct drm_file *file_priv);
115void radeon_gem_object_close(struct drm_gem_object *obj, 115void radeon_gem_object_close(struct drm_gem_object *obj,
116 struct drm_file *file_priv); 116 struct drm_file *file_priv);
117struct dma_buf *radeon_gem_prime_export(struct drm_device *dev,
118 struct drm_gem_object *gobj,
119 int flags);
117extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, 120extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
118 unsigned int flags, 121 unsigned int flags,
119 int *vpos, int *hpos, ktime_t *stime, 122 int *vpos, int *hpos, ktime_t *stime,
@@ -568,7 +571,7 @@ static struct drm_driver kms_driver = {
568 571
569 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 572 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
570 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 573 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
571 .gem_prime_export = drm_gem_prime_export, 574 .gem_prime_export = radeon_gem_prime_export,
572 .gem_prime_import = drm_gem_prime_import, 575 .gem_prime_import = drm_gem_prime_import,
573 .gem_prime_pin = radeon_gem_prime_pin, 576 .gem_prime_pin = radeon_gem_prime_pin,
574 .gem_prime_unpin = radeon_gem_prime_unpin, 577 .gem_prime_unpin = radeon_gem_prime_unpin,
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index bfd7e1b0ff3f..993ab223b503 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -272,6 +272,65 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
272 return 0; 272 return 0;
273} 273}
274 274
275int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
276 struct drm_file *filp)
277{
278 struct radeon_device *rdev = dev->dev_private;
279 struct drm_radeon_gem_userptr *args = data;
280 struct drm_gem_object *gobj;
281 struct radeon_bo *bo;
282 uint32_t handle;
283 int r;
284
285 if (offset_in_page(args->addr | args->size))
286 return -EINVAL;
287
288 /* we only support read only mappings for now */
289 if (!(args->flags & RADEON_GEM_USERPTR_READONLY))
290 return -EACCES;
291
292 /* reject unknown flag values */
293 if (args->flags & ~RADEON_GEM_USERPTR_READONLY)
294 return -EINVAL;
295
296 /* readonly pages not tested on older hardware */
297 if (rdev->family < CHIP_R600)
298 return -EINVAL;
299
300 down_read(&rdev->exclusive_lock);
301
302 /* create a gem object to contain this object in */
303 r = radeon_gem_object_create(rdev, args->size, 0,
304 RADEON_GEM_DOMAIN_CPU, 0,
305 false, &gobj);
306 if (r)
307 goto handle_lockup;
308
309 bo = gem_to_radeon_bo(gobj);
310 r = radeon_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);
311 if (r)
312 goto release_object;
313
314 r = drm_gem_handle_create(filp, gobj, &handle);
315 /* drop reference from allocate - handle holds it now */
316 drm_gem_object_unreference_unlocked(gobj);
317 if (r)
318 goto handle_lockup;
319
320 args->handle = handle;
321 up_read(&rdev->exclusive_lock);
322 return 0;
323
324release_object:
325 drm_gem_object_unreference_unlocked(gobj);
326
327handle_lockup:
328 up_read(&rdev->exclusive_lock);
329 r = radeon_gem_handle_lockup(rdev, r);
330