From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jerome Glisse Subject: Re: [PATCH 2/2] drm/radeon: add user pointer support v3 Date: Thu, 10 Jul 2014 10:20:53 -0400 Message-ID: <20140710142050.GA17335@gmail.com> References: <1404995632-6803-1-git-send-email-deathsimple@vodafone.de> <1404995632-6803-2-git-send-email-deathsimple@vodafone.de> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mail-ie0-f169.google.com (mail-ie0-f169.google.com [209.85.223.169]) by gabe.freedesktop.org (Postfix) with ESMTP id 297596E36C for ; Thu, 10 Jul 2014 07:21:01 -0700 (PDT) Received: by mail-ie0-f169.google.com with SMTP id rl12so7570482iec.14 for ; Thu, 10 Jul 2014 07:21:00 -0700 (PDT) Content-Disposition: inline In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Alex Deucher Cc: Maling list - DRI developers List-Id: dri-devel@lists.freedesktop.org On Thu, Jul 10, 2014 at 09:48:49AM -0400, Alex Deucher wrote: > On Thu, Jul 10, 2014 at 8:33 AM, Christian K=F6nig > wrote: > > From: Christian K=F6nig > > > > 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 > > > > Signed-off-by: Christian K=F6nig > = > Reviewed-by: Alex Deucher Well i am not oppose to userptr even if i dislike it and this version do not have the crazy mmu_notifier thing so. Reviewed-by: J=E9r=F4me Glisse > = > > --- > > drivers/gpu/drm/radeon/radeon.h | 4 ++ > > drivers/gpu/drm/radeon/radeon_cs.c | 25 +++++++- > > drivers/gpu/drm/radeon/radeon_drv.c | 5 +- > > drivers/gpu/drm/radeon/radeon_gem.c | 67 +++++++++++++++++++++ > > 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 | 107 +++++++++++++++++++++++++= +++++++- > > drivers/gpu/drm/radeon/radeon_vm.c | 3 + > > include/uapi/drm/radeon_drm.h | 11 ++++ > > 10 files changed, 232 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/r= adeon.h > > index 86fdfa30..55c996e 100644 > > --- a/drivers/gpu/drm/radeon/radeon.h > > +++ b/drivers/gpu/drm/radeon/radeon.h > > @@ -2111,6 +2111,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_import_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, > > @@ -2803,6 +2805,8 @@ extern void radeon_legacy_set_clock_gating(struct= radeon_device *rdev, int enabl > > extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, i= nt enable); > > extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u3= 2 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 user= ptr); > > +extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm); > > extern void radeon_vram_location(struct radeon_device *rdev, struct ra= deon_mc *mc, u64 base); > > extern void radeon_gtt_location(struct radeon_device *rdev, struct rad= eon_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/radeo= n/radeon_cs.c > > index 71a1434..be65311 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_p= arser *p) > > struct radeon_cs_chunk *chunk; > > struct radeon_cs_buckets buckets; > > unsigned i, j; > > - bool duplicate; > > + bool duplicate, need_mmap_lock =3D false; > > + int r; > > > > if (p->chunk_relocs_idx =3D=3D -1) { > > return 0; > > @@ -164,6 +165,19 @@ static int radeon_cs_parser_relocs(struct radeon_c= s_parser *p) > > p->relocs[i].allowed_domains =3D domain; > > } > > > > + if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.tt= m)) { > > + uint32_t domain =3D p->relocs[i].prefered_domai= ns; > > + if (!(domain & RADEON_GEM_DOMAIN_GTT)) { > > + DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT i= s " > > + "allowed for userptr BOs\n"); > > + return -EINVAL; > > + } > > + need_mmap_lock =3D true; > > + domain =3D RADEON_GEM_DOMAIN_GTT; > > + p->relocs[i].prefered_domains =3D domain; > > + p->relocs[i].allowed_domains =3D domain; > > + } > > + > > p->relocs[i].tv.bo =3D &p->relocs[i].robj->tbo; > > p->relocs[i].handle =3D r->handle; > > > > @@ -176,8 +190,15 @@ static int radeon_cs_parser_relocs(struct radeon_c= s_parser *p) > > if (p->cs_flags & RADEON_CS_USE_VM) > > p->vm_bos =3D radeon_vm_get_bos(p->rdev, p->ib.vm, > > &p->validated); > > + if (need_mmap_lock) > > + down_read(¤t->mm->mmap_sem); > > + > > + r =3D radeon_bo_list_validate(p->rdev, &p->ticket, &p->validate= d, p->ring); > > > > - return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validat= ed, p->ring); > > + if (need_mmap_lock) > > + up_read(¤t->mm->mmap_sem); > > + > > + return r; > > } > > > > static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s3= 2 priority) > > diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/rade= on/radeon_drv.c > > index cb14213..bf91879 100644 > > --- a/drivers/gpu/drm/radeon/radeon_drv.c > > +++ b/drivers/gpu/drm/radeon/radeon_drv.c > > @@ -112,6 +112,9 @@ int radeon_gem_object_open(struct drm_gem_object *o= bj, > > struct drm_file *file_priv); > > void radeon_gem_object_close(struct drm_gem_object *obj, > > struct drm_file *file_priv); > > +struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, > > + struct drm_gem_object *gobj, > > + int flags); > > extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, > > unsigned int flags, > > int *vpos, int *hpos, ktime_t *st= ime, > > @@ -562,7 +565,7 @@ static struct drm_driver kms_driver =3D { > > > > .prime_handle_to_fd =3D drm_gem_prime_handle_to_fd, > > .prime_fd_to_handle =3D drm_gem_prime_fd_to_handle, > > - .gem_prime_export =3D drm_gem_prime_export, > > + .gem_prime_export =3D radeon_gem_prime_export, > > .gem_prime_import =3D drm_gem_prime_import, > > .gem_prime_pin =3D radeon_gem_prime_pin, > > .gem_prime_unpin =3D radeon_gem_prime_unpin, > > diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/rade= on/radeon_gem.c > > index d09650c..2464c65 100644 > > --- a/drivers/gpu/drm/radeon/radeon_gem.c > > +++ b/drivers/gpu/drm/radeon/radeon_gem.c > > @@ -272,6 +272,64 @@ int radeon_gem_create_ioctl(struct drm_device *dev= , void *data, > > return 0; > > } > > > > +int radeon_gem_import_ioctl(struct drm_device *dev, void *data, > > + struct drm_file *filp) > > +{ > > + struct radeon_device *rdev =3D dev->dev_private; > > + struct drm_radeon_gem_import *args =3D data; > > + struct drm_gem_object *gobj; > > + struct radeon_bo *bo; > > + uint32_t handle; > > + int r; > > + > > + if (offset_in_page(args->addr | args->size)) > > + return -EINVAL; > > + > > + /* we only support read only mappings for now */ > > + if (!(args->flags & RADEON_GEM_IMPORT_READONLY)) > > + return -EACCES; > > + > > + /* readonly pages not tested on older hardware */ > > + if (rdev->family < CHIP_R600) > > + return -EINVAL; > > + > > + if (!access_ok(VERIFY_READ, (char __user *)args->addr, args->si= ze)) > > + return -EFAULT; > > + > > + down_read(&rdev->exclusive_lock); > > + > > + /* create a gem object to contain this object in */ > > + r =3D radeon_gem_object_create(rdev, args->size, 0, > > + RADEON_GEM_DOMAIN_CPU, > > + false, false, &gobj); > > + if (r) > > + goto handle_lockup; > > + > > + bo =3D gem_to_radeon_bo(gobj); > > + r =3D radeon_ttm_tt_set_userptr(bo->tbo.ttm, args->addr); > > + if (r) > > + goto release_object; > > + > > + r =3D drm_gem_handle_create(filp, gobj, &handle); > > + /* drop reference from allocate - handle holds it now */ > > + drm_gem_object_unreference_unlocked(gobj); > > + if (r) > > + goto handle_lockup; > > + > > + args->handle =3D handle; > > + up_read(&rdev->exclusive_lock); > > + return 0; > > + > > +release_object: > > + drm_gem_object_unreference_unlocked(gobj); > > + > > +handle_lockup: > > + up_read(&rdev->exclusive_lock); > > + r =3D radeon_gem_handle_lockup(rdev, r); > > + > > + return r; > > +} > > + > > int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, > > struct drm_file *filp) > > { > > @@ -315,6 +373,10 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, > > return -ENOENT; > > } > > robj =3D gem_to_radeon_bo(gobj); > > + if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { > > + drm_gem_object_unreference_unlocked(gobj); > > + return -EPERM; > > + } > > *offset_p =3D radeon_bo_mmap_offset(robj); > > drm_gem_object_unreference_unlocked(gobj); > > return 0; > > @@ -535,6 +597,11 @@ int radeon_gem_op_ioctl(struct drm_device *dev, vo= id *data, > > return -ENOENT; > > } > > robj =3D gem_to_radeon_bo(gobj); > > + > > + r =3D -EPERM; > > + if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) > > + goto out; > > + > > r =3D radeon_bo_reserve(robj, false); > > if (unlikely(r)) > > goto out; > > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/rade= on/radeon_kms.c > > index 35d9318..39e8a5c 100644 > > --- a/drivers/gpu/drm/radeon/radeon_kms.c > > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > > @@ -874,5 +874,6 @@ const struct drm_ioctl_desc radeon_ioctls_kms[] =3D= { > > DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_A= UTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), > > DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|= DRM_UNLOCKED|DRM_RENDER_ALLOW), > > DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|= DRM_UNLOCKED|DRM_RENDER_ALLOW), > > + DRM_IOCTL_DEF_DRV(RADEON_GEM_IMPORT, radeon_gem_import_ioctl, D= RM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), > > }; > > int radeon_max_kms_ioctl =3D ARRAY_SIZE(radeon_ioctls_kms); > > diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/r= adeon/radeon_object.c > > index 6c717b2..c1f826b 100644 > > --- a/drivers/gpu/drm/radeon/radeon_object.c > > +++ b/drivers/gpu/drm/radeon/radeon_object.c > > @@ -253,6 +253,9 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, = u32 domain, u64 max_offset, > > { > > int r, i; > > > > + if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) > > + return -EPERM; > > + > > if (bo->pin_count) { > > bo->pin_count++; > > if (gpu_addr) > > diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/ra= deon/radeon_prime.c > > index 2007456..1f0d8f7 100644 > > --- a/drivers/gpu/drm/radeon/radeon_prime.c > > +++ b/drivers/gpu/drm/radeon/radeon_prime.c > > @@ -103,3 +103,13 @@ void radeon_gem_prime_unpin(struct drm_gem_object = *obj) > > radeon_bo_unpin(bo); > > radeon_bo_unreserve(bo); > > } > > + > > +struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, > > + struct drm_gem_object *gobj, > > + int flags) > > +{ > > + struct radeon_bo *bo =3D gem_to_radeon_bo(gobj); > > + if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) > > + return ERR_PTR(-EPERM); > > + return drm_gem_prime_export(dev, gobj, flags); > > +} > > diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/rade= on/radeon_ttm.c > > index 19d662f..fee6018 100644 > > --- a/drivers/gpu/drm/radeon/radeon_ttm.c > > +++ b/drivers/gpu/drm/radeon/radeon_ttm.c > > @@ -515,12 +515,16 @@ struct radeon_ttm_tt { > > struct ttm_dma_tt ttm; > > struct radeon_device *rdev; > > u64 offset; > > + > > + uint64_t userptr; > > + struct mm_struct *usermm; > > }; > > > > static int radeon_ttm_backend_bind(struct ttm_tt *ttm, > > struct ttm_mem_reg *bo_mem) > > { > > struct radeon_ttm_tt *gtt =3D (void*)ttm; > > + uint32_t flags =3D gtt->userptr ? RADEON_GART_PAGE_READONLY : 0; > > int r; > > > > gtt->offset =3D (unsigned long)(bo_mem->start << PAGE_SHIFT); > > @@ -529,7 +533,7 @@ static int radeon_ttm_backend_bind(struct ttm_tt *t= tm, > > ttm->num_pages, bo_mem, ttm); > > } > > r =3D radeon_gart_bind(gtt->rdev, gtt->offset, ttm->num_pages, > > - ttm->pages, gtt->ttm.dma_address, 0); > > + ttm->pages, gtt->ttm.dma_address, flags); > > if (r) { > > DRM_ERROR("failed to bind %lu pages at 0x%08X\n", > > ttm->num_pages, (unsigned)gtt->offset); > > @@ -588,6 +592,73 @@ static struct ttm_tt *radeon_ttm_tt_create(struct = ttm_bo_device *bdev, > > return >t->ttm.ttm; > > } > > > > +static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) > > +{ > > + struct radeon_device *rdev =3D radeon_get_rdev(ttm->bdev); > > + struct radeon_ttm_tt *gtt =3D (void *)ttm; > > + unsigned pinned =3D 0, nents; > > + int r; > > + > > + /* prepare the sg table with the user pages */ > > + if (current->mm !=3D gtt->usermm) > > + return -EPERM; > > + > > + do { > > + unsigned num_pages =3D ttm->num_pages - pinned; > > + uint64_t userptr =3D gtt->userptr + pinned * PAGE_SIZE; > > + struct page **pages =3D ttm->pages + pinned; > > + > > + r =3D get_user_pages(current, current->mm, userptr, num= _pages, > > + 0, 0, pages, NULL); > > + if (r < 0) { > > + release_pages(ttm->pages, pinned, 0); > > + return r; > > + } > > + pinned +=3D r; > > + > > + } while (pinned < ttm->num_pages); > > + > > + r =3D -ENOMEM; > > + ttm->sg =3D kcalloc(1, sizeof(struct sg_table), GFP_KERNEL); > > + if (!ttm->sg) > > + goto release_pages; > > + > > + r =3D sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_p= ages, 0, > > + ttm->num_pages << PAGE_SHIFT, > > + GFP_KERNEL); > > + if (r) > > + goto release_sg; > > + > > + r =3D -ENOMEM; > > + nents =3D dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, > > + DMA_TO_DEVICE); > > + if (nents !=3D ttm->sg->nents) > > + goto release_sg; > > + > > + return 0; > > + > > +release_sg: > > + kfree(ttm->sg); > > + > > +release_pages: > > + release_pages(ttm->pages, pinned, 0); > > + return r; > > +} > > + > > +static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) > > +{ > > + struct radeon_device *rdev =3D radeon_get_rdev(ttm->bdev); > > + > > + /* free the sg table and pages again */ > > + dma_unmap_sg(rdev->dev, ttm->sg->sgl, > > + ttm->sg->nents, DMA_TO_DEVICE); > > + > > + sg_free_table(ttm->sg); > > + kfree(ttm->sg); > > + > > + release_pages(ttm->pages, ttm->num_pages, 0); > > +} > > + > > static int radeon_ttm_tt_populate(struct ttm_tt *ttm) > > { > > struct radeon_device *rdev; > > @@ -599,6 +670,13 @@ static int radeon_ttm_tt_populate(struct ttm_tt *t= tm) > > if (ttm->state !=3D tt_unpopulated) > > return 0; > > > > + if (gtt->userptr) { > > + r =3D radeon_ttm_tt_pin_userptr(ttm); > > + if (r) > > + return r; > > + slave =3D true; > > + } > > + > > if (slave && ttm->sg) { > > drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, > > gtt->ttm.dma_address, = ttm->num_pages); > > @@ -648,6 +726,11 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt= *ttm) > > unsigned i; > > bool slave =3D !!(ttm->page_flags & TTM_PAGE_FLAG_SG); > > > > + if (gtt->userptr) { > > + radeon_ttm_tt_unpin_userptr(ttm); > > + return; > > + } > > + > > if (slave) > > return; > > > > @@ -676,6 +759,28 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt= *ttm) > > ttm_pool_unpopulate(ttm); > > } > > > > +int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t userptr) > > +{ > > + struct radeon_ttm_tt *gtt =3D (void *)ttm; > > + > > + if (gtt =3D=3D NULL) > > + return -EINVAL; > > + > > + gtt->userptr =3D userptr; > > + gtt->usermm =3D current->mm; > > + return 0; > > +} > > + > > +bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm) > > +{ > > + struct radeon_ttm_tt *gtt =3D (void *)ttm; > > + > > + if (gtt =3D=3D NULL) > > + return false; > > + > > + return !!gtt->userptr; > > +} > > + > > static struct ttm_bo_driver radeon_bo_driver =3D { > > .ttm_tt_create =3D &radeon_ttm_tt_create, > > .ttm_tt_populate =3D &radeon_ttm_tt_populate, > > diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeo= n/radeon_vm.c > > index eecff6b..99663a8 100644 > > --- a/drivers/gpu/drm/radeon/radeon_vm.c > > +++ b/drivers/gpu/drm/radeon/radeon_vm.c > > @@ -850,6 +850,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev, > > > > bo_va->flags &=3D ~RADEON_VM_PAGE_VALID; > > bo_va->flags &=3D ~RADEON_VM_PAGE_SYSTEM; > > + if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) > > + bo_va->flags &=3D ~RADEON_VM_PAGE_WRITEABLE; > > + > > if (mem) { > > addr =3D mem->start << PAGE_SHIFT; > > if (mem->mem_type !=3D TTM_PL_SYSTEM) { > > diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_dr= m.h > > index 1cc0b61..64ef99c 100644 > > --- a/include/uapi/drm/radeon_drm.h > > +++ b/include/uapi/drm/radeon_drm.h > > @@ -511,6 +511,7 @@ typedef struct { > > #define DRM_RADEON_GEM_BUSY 0x2a > > #define DRM_RADEON_GEM_VA 0x2b > > #define DRM_RADEON_GEM_OP 0x2c > > +#define DRM_RADEON_GEM_IMPORT 0x2d > > > > #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RA= DEON_CP_INIT, drm_radeon_init_t) > > #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RA= DEON_CP_START) > > @@ -554,6 +555,7 @@ typedef struct { > > #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM= _RADEON_GEM_BUSY, struct drm_radeon_gem_busy) > > #define DRM_IOCTL_RADEON_GEM_VA DRM_IOWR(DRM_COMMAND_BA= SE + DRM_RADEON_GEM_VA, struct drm_radeon_gem_va) > > #define DRM_IOCTL_RADEON_GEM_OP DRM_IOWR(DRM_COMMAND_BA= SE + DRM_RADEON_GEM_OP, struct drm_radeon_gem_op) > > +#define DRM_IOCTL_RADEON_GEM_IMPORT DRM_IOWR(DRM_COMMAND_BASE + DRM= _RADEON_GEM_IMPORT, struct drm_radeon_gem_import) > > > > typedef struct drm_radeon_init { > > enum { > > @@ -806,6 +808,15 @@ struct drm_radeon_gem_create { > > uint32_t flags; > > }; > > > > +#define RADEON_GEM_IMPORT_READONLY 0x1 > > + > > +struct drm_radeon_gem_import { > > + uint64_t addr; > > + uint64_t size; > > + uint32_t flags; > > + uint32_t handle; > > +}; > > + > > #define RADEON_TILING_MACRO 0x1 > > #define RADEON_TILING_MICRO 0x2 > > #define RADEON_TILING_SWAP_16BIT 0x4 > > -- > > 1.9.1 > > > > _______________________________________________ > > dri-devel mailing list > > dri-devel@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel