[PATCH 1/5] drm/radeon: add userptr support v6

2014-08-05 Thread Christian König
Am 05.08.2014 um 16:30 schrieb Jerome Glisse:
> On Tue, Aug 05, 2014 at 04:11:03PM +0200, Christian K?nig wrote:
>> From: Christian K?nig 
>>
>> This patch adds an IOCTL for turning a pointer supplied by
>> userspace into a buffer object.
>>
>> It imposes several restrictions upon the memory being mapped:
>>
>> 1. It must be page aligned (both start/end addresses, i.e ptr and size).
>>
>> 2. It must be normal system memory, not a pointer into another map of IO
>> space (e.g. it must not be a GTT mmapping of another object).
>>
>> 3. The BO is mapped into GTT, so the maximum amount of memory mapped at
>> all times is still the GTT limit.
>>
>> 4. The BO is only mapped readonly for now, so no write support.
>>
>> 5. List of backing pages is only acquired once, so they represent a
>> snapshot of the first use.
>>
>> Exporting and sharing as well as mapping of buffer objects created by
>> this function is forbidden and results in an -EPERM.
>>
>> v2: squash all previous changes into first public version
>> v3: fix tabs, map readonly, don't use MM callback any more
>> v4: set TTM_PAGE_FLAG_SG so that TTM never messes with the pages,
>>  pin/unpin pages on bind/unbind instead of populate/unpopulate
>> v5: rebased on 3.17-wip, IOCTL renamed to userptr, reject any unknown
>>  flags, better handle READONLY flag, improve permission check
>> v6: fix ptr cast warning, use set_page_dirty/mark_page_accessed on unpin
>>
>> Signed-off-by: Christian K?nig 
>> Reviewed-by: Alex Deucher  (v4)
>> Reviewed-by: J?r?me Glisse  (v4)
>> ---
>>   drivers/gpu/drm/radeon/radeon.h|   5 ++
>>   drivers/gpu/drm/radeon/radeon_cs.c |  25 +-
>>   drivers/gpu/drm/radeon/radeon_drv.c|   5 +-
>>   drivers/gpu/drm/radeon/radeon_gem.c|  68 
>>   drivers/gpu/drm/radeon/radeon_kms.c|   1 +
>>   drivers/gpu/drm/radeon/radeon_object.c |   3 +
>>   drivers/gpu/drm/radeon/radeon_prime.c  |  10 +++
>>   drivers/gpu/drm/radeon/radeon_ttm.c| 139 
>> +
>>   drivers/gpu/drm/radeon/radeon_vm.c |   3 +
>>   include/uapi/drm/radeon_drm.h  |  11 +++
>>   10 files changed, 267 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon.h 
>> b/drivers/gpu/drm/radeon/radeon.h
>> index 9e1732e..3c6999e 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,
>>struct drm_file *filp);
>>   int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
>>  struct drm_file *filp);
>> +int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
>> + struct drm_file *filp);
>>   int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
>>   struct drm_file *file_priv);
>>   int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
>> @@ -2871,6 +2873,9 @@ extern void radeon_legacy_set_clock_gating(struct 
>> radeon_device *rdev, int enabl
>>   extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int 
>> enable);
>>   extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 
>> domain);
>>   extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
>> +extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
>> + uint32_t flags);
>> +extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm);
>>   extern void radeon_vram_location(struct radeon_device *rdev, struct 
>> radeon_mc *mc, u64 base);
>>   extern void radeon_gtt_location(struct radeon_device *rdev, struct 
>> radeon_mc *mc);
>>   extern 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 ee712c1..1321491 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)
>>  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;
>> @@ -164,6 +165,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;
>> +}
>> + 

[PATCH 1/5] drm/radeon: add userptr support v6

2014-08-05 Thread Christian König
From: Christian K?nig 

This patch adds an IOCTL for turning a pointer supplied by
userspace into a buffer object.

It imposes several restrictions upon the memory being mapped:

1. It must be page aligned (both start/end addresses, i.e ptr and size).

2. It must be normal system memory, not a pointer into another map of IO
space (e.g. it must not be a GTT mmapping of another object).

3. The BO is mapped into GTT, so the maximum amount of memory mapped at
all times is still the GTT limit.

4. The BO is only mapped readonly for now, so no write support.

5. List of backing pages is only acquired once, so they represent a
snapshot of the first use.

Exporting and sharing as well as mapping of buffer objects created by
this function is forbidden and results in an -EPERM.

v2: squash all previous changes into first public version
v3: fix tabs, map readonly, don't use MM callback any more
v4: set TTM_PAGE_FLAG_SG so that TTM never messes with the pages,
pin/unpin pages on bind/unbind instead of populate/unpopulate
v5: rebased on 3.17-wip, IOCTL renamed to userptr, reject any unknown
flags, better handle READONLY flag, improve permission check
v6: fix ptr cast warning, use set_page_dirty/mark_page_accessed on unpin

Signed-off-by: Christian K?nig 
Reviewed-by: Alex Deucher  (v4)
Reviewed-by: J?r?me Glisse  (v4)
---
 drivers/gpu/drm/radeon/radeon.h|   5 ++
 drivers/gpu/drm/radeon/radeon_cs.c |  25 +-
 drivers/gpu/drm/radeon/radeon_drv.c|   5 +-
 drivers/gpu/drm/radeon/radeon_gem.c|  68 
 drivers/gpu/drm/radeon/radeon_kms.c|   1 +
 drivers/gpu/drm/radeon/radeon_object.c |   3 +
 drivers/gpu/drm/radeon/radeon_prime.c  |  10 +++
 drivers/gpu/drm/radeon/radeon_ttm.c| 139 +
 drivers/gpu/drm/radeon/radeon_vm.c |   3 +
 include/uapi/drm/radeon_drm.h  |  11 +++
 10 files changed, 267 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9e1732e..3c6999e 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,
  struct drm_file *filp);
 int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
+int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
+struct drm_file *filp);
 int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_priv);
 int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
@@ -2871,6 +2873,9 @@ extern void radeon_legacy_set_clock_gating(struct 
radeon_device *rdev, int enabl
 extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int 
enable);
 extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 
domain);
 extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
+extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
+uint32_t flags);
+extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm);
 extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc 
*mc, u64 base);
 extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc 
*mc);
 extern 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 ee712c1..1321491 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)
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;
@@ -164,6 +165,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 = >relocs[i].robj->tbo;
p->relocs[i].handle = r->handle;

@@ -176,8 

[PATCH 1/5] drm/radeon: add userptr support v6

2014-08-05 Thread Jerome Glisse
On Tue, Aug 05, 2014 at 04:11:03PM +0200, Christian K?nig wrote:
> From: Christian K?nig 
> 
> This patch adds an IOCTL for turning a pointer supplied by
> userspace into a buffer object.
> 
> It imposes several restrictions upon the memory being mapped:
> 
> 1. It must be page aligned (both start/end addresses, i.e ptr and size).
> 
> 2. It must be normal system memory, not a pointer into another map of IO
> space (e.g. it must not be a GTT mmapping of another object).
> 
> 3. The BO is mapped into GTT, so the maximum amount of memory mapped at
> all times is still the GTT limit.
> 
> 4. The BO is only mapped readonly for now, so no write support.
> 
> 5. List of backing pages is only acquired once, so they represent a
> snapshot of the first use.
> 
> Exporting and sharing as well as mapping of buffer objects created by
> this function is forbidden and results in an -EPERM.
> 
> v2: squash all previous changes into first public version
> v3: fix tabs, map readonly, don't use MM callback any more
> v4: set TTM_PAGE_FLAG_SG so that TTM never messes with the pages,
> pin/unpin pages on bind/unbind instead of populate/unpopulate
> v5: rebased on 3.17-wip, IOCTL renamed to userptr, reject any unknown
> flags, better handle READONLY flag, improve permission check
> v6: fix ptr cast warning, use set_page_dirty/mark_page_accessed on unpin
> 
> Signed-off-by: Christian K?nig 
> Reviewed-by: Alex Deucher  (v4)
> Reviewed-by: J?r?me Glisse  (v4)
> ---
>  drivers/gpu/drm/radeon/radeon.h|   5 ++
>  drivers/gpu/drm/radeon/radeon_cs.c |  25 +-
>  drivers/gpu/drm/radeon/radeon_drv.c|   5 +-
>  drivers/gpu/drm/radeon/radeon_gem.c|  68 
>  drivers/gpu/drm/radeon/radeon_kms.c|   1 +
>  drivers/gpu/drm/radeon/radeon_object.c |   3 +
>  drivers/gpu/drm/radeon/radeon_prime.c  |  10 +++
>  drivers/gpu/drm/radeon/radeon_ttm.c| 139 
> +
>  drivers/gpu/drm/radeon/radeon_vm.c |   3 +
>  include/uapi/drm/radeon_drm.h  |  11 +++
>  10 files changed, 267 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 9e1732e..3c6999e 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,
> struct drm_file *filp);
>  int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
>   struct drm_file *filp);
> +int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data,
> +  struct drm_file *filp);
>  int radeon_gem_pin_ioctl(struct drm_device *dev, void *data,
>struct drm_file *file_priv);
>  int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data,
> @@ -2871,6 +2873,9 @@ extern void radeon_legacy_set_clock_gating(struct 
> radeon_device *rdev, int enabl
>  extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int 
> enable);
>  extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 
> domain);
>  extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
> +extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
> +  uint32_t flags);
> +extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm);
>  extern void radeon_vram_location(struct radeon_device *rdev, struct 
> radeon_mc *mc, u64 base);
>  extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc 
> *mc);
>  extern 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 ee712c1..1321491 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)
>   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;
> @@ -164,6 +165,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 =