Merge branch 'drm-next-3.18' of git://people.freedesktop.org/~agd5f/linux into drm...
[cascardo/linux.git] / drivers / gpu / drm / radeon / radeon_cs.c
index 83f382e..0669399 100644 (file)
@@ -78,7 +78,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
        struct radeon_cs_chunk *chunk;
        struct radeon_cs_buckets buckets;
        unsigned i, j;
-       bool duplicate;
+       bool duplicate, need_mmap_lock = false;
+       int r;
 
        if (p->chunk_relocs_idx == -1) {
                return 0;
@@ -165,6 +166,19 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
                        p->relocs[i].allowed_domains = domain;
                }
 
+               if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) {
+                       uint32_t domain = p->relocs[i].prefered_domains;
+                       if (!(domain & RADEON_GEM_DOMAIN_GTT)) {
+                               DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is "
+                                         "allowed for userptr BOs\n");
+                               return -EINVAL;
+                       }
+                       need_mmap_lock = true;
+                       domain = RADEON_GEM_DOMAIN_GTT;
+                       p->relocs[i].prefered_domains = domain;
+                       p->relocs[i].allowed_domains = domain;
+               }
+
                p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
                p->relocs[i].handle = r->handle;
 
@@ -177,8 +191,15 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
        if (p->cs_flags & RADEON_CS_USE_VM)
                p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
                                              &p->validated);
+       if (need_mmap_lock)
+               down_read(&current->mm->mmap_sem);
+
+       r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
 
-       return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
+       if (need_mmap_lock)
+               up_read(&current->mm->mmap_sem);
+
+       return r;
 }
 
 static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority)