Hi! Could we perhaps get an ack from Radeon / Nouveau as well? Thanks, Thomas On 11/12/2014 12:55 PM, Thomas Hellstrom wrote: > It happens on occasion that developers of generic user-space applications > abuse the dumb buffer API to get hold of drm buffers that they can both > mmap() and use for GPU acceleration, using the assumptions that dumb buffers > and buffers available for GPU are > a) The same type and can be aribtrarily type-casted. > b) fully coherent. > > This patch makes the most widely used drivers warn nicely when that happens, > the next step will be to fail. > > Signed-off-by: Thomas Hellstrom <thellstrom@xxxxxxxxxx> > --- > Patch is only compile-tested. > FWIW vmware should typically fail on these errors. > > --- > drivers/gpu/drm/i915/i915_drv.c | 2 +- > drivers/gpu/drm/i915/i915_drv.h | 5 +++-- > drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++++++++++++++++----- > drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ > drivers/gpu/drm/nouveau/nouveau_display.c | 9 +++++++++ > drivers/gpu/drm/nouveau/nouveau_gem.c | 3 +++ > drivers/gpu/drm/radeon/radeon_gem.c | 29 ++++++++++++++++++++++++++++- > drivers/gpu/drm/radeon/radeon_object.c | 3 +++ > include/drm/drmP.h | 7 +++++++ > 9 files changed, 80 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index e27cdbe..956b154 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -1593,7 +1593,7 @@ static struct drm_driver driver = { > .gem_prime_import = i915_gem_prime_import, > > .dumb_create = i915_gem_dumb_create, > - .dumb_map_offset = i915_gem_mmap_gtt, > + .dumb_map_offset = i915_gem_dumb_map_offset, > .dumb_destroy = drm_gem_dumb_destroy, > .ioctls = i915_ioctls, > .fops = &i915_driver_fops, > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 7a830ea..669537c 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -2321,8 +2321,9 @@ void i915_vma_move_to_active(struct i915_vma *vma, > int i915_gem_dumb_create(struct drm_file *file_priv, > struct drm_device *dev, > struct drm_mode_create_dumb *args); > -int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, > - uint32_t handle, uint64_t *offset); > +int i915_gem_dumb_map_offset(struct drm_file *file_priv, > + struct drm_device *dev, uint32_t handle, > + uint64_t *offset); > /** > * Returns true if seq1 is later than seq2. > */ > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index ba7f5c6..3d97a43 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -347,6 +347,7 @@ static int > i915_gem_create(struct drm_file *file, > struct drm_device *dev, > uint64_t size, > + bool dumb, > uint32_t *handle_p) > { > struct drm_i915_gem_object *obj; > @@ -362,6 +363,7 @@ i915_gem_create(struct drm_file *file, > if (obj == NULL) > return -ENOMEM; > > + obj->base.dumb = dumb; > ret = drm_gem_handle_create(file, &obj->base, &handle); > /* drop reference from allocate - handle holds it now */ > drm_gem_object_unreference_unlocked(&obj->base); > @@ -381,7 +383,7 @@ i915_gem_dumb_create(struct drm_file *file, > args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); > args->size = args->pitch * args->height; > return i915_gem_create(file, dev, > - args->size, &args->handle); > + args->size, true, &args->handle); > } > > /** > @@ -394,7 +396,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, > struct drm_i915_gem_create *args = data; > > return i915_gem_create(file, dev, > - args->size, &args->handle); > + args->size, false, &args->handle); > } > > static inline int > @@ -1750,10 +1752,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) > drm_gem_free_mmap_offset(&obj->base); > } > > -int > +static int > i915_gem_mmap_gtt(struct drm_file *file, > struct drm_device *dev, > - uint32_t handle, > + uint32_t handle, bool dumb, > uint64_t *offset) > { > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -1770,6 +1772,13 @@ i915_gem_mmap_gtt(struct drm_file *file, > goto unlock; > } > > + /* > + * We don't allow dumb mmaps on objects created using another > + * interface. > + */ > + WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach), > + "Illegal dumb map of accelerated buffer.\n"); > + > if (obj->base.size > dev_priv->gtt.mappable_end) { > ret = -E2BIG; > goto out; > @@ -1794,6 +1803,15 @@ unlock: > return ret; > } > > +int > +i915_gem_dumb_map_offset(struct drm_file *file, > + struct drm_device *dev, > + uint32_t handle, > + uint64_t *offset) > +{ > + return i915_gem_mmap_gtt(file, dev, handle, true, offset); > +} > + > /** > * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing > * @dev: DRM device > @@ -1815,7 +1833,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, > { > struct drm_i915_gem_mmap_gtt *args = data; > > - return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); > + return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset); > } > > static inline int > diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c > index 60998fc..ba78ea0 100644 > --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c > +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c > @@ -120,6 +120,9 @@ eb_lookup_vmas(struct eb_vmas *eb, > ret = -EINVAL; > goto err; > } > + > + WARN_ONCE(obj->base.dumb, > + "GPU use of dumb buffer is illegal.\n"); > > drm_gem_object_reference(&obj->base); > list_add_tail(&obj->obj_exec_link, &objects); > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c > index 65b4fd5..63f746a 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_display.c > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c > @@ -867,6 +867,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, > if (ret) > return ret; > > + bo->gem.dumb = true; > ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); > drm_gem_object_unreference_unlocked(&bo->gem); > return ret; > @@ -882,6 +883,14 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, > gem = drm_gem_object_lookup(dev, file_priv, handle); > if (gem) { > struct nouveau_bo *bo = nouveau_gem_object(gem); > + > + /* > + * We don't allow dumb mmaps on objects created using another > + * interface. > + */ > + WARN_ONCE(!(gem->dumb || gem->import_attach), > + "Illegal dumb map of accelerated buffer.\n"); > + > *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); > drm_gem_object_unreference_unlocked(gem); > return 0; > diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c > index 292a677..92ba48e 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_gem.c > +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c > @@ -459,6 +459,9 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, > list_for_each_entry(nvbo, list, entry) { > struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; > > + WARN_ONCE(nvbo->gem.dumb, > + "GPU use of dumb buffer is illegal.\n"); > + > ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, > b->write_domains, > b->valid_domains); > diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c > index bfd7e1b..cbfba17 100644 > --- a/drivers/gpu/drm/radeon/radeon_gem.c > +++ b/drivers/gpu/drm/radeon/radeon_gem.c > @@ -303,6 +303,24 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, > return r; > } > > +static int radeon_mode_mmap(struct drm_file *filp, > + struct drm_device *dev, > + uint32_t handle, uint64_t *offset_p) > +{ > + struct drm_gem_object *gobj; > + struct radeon_bo *robj; > + > + gobj = drm_gem_object_lookup(dev, filp, handle); > + if (gobj == NULL) { > + return -ENOENT; > + } > + > + robj = gem_to_radeon_bo(gobj); > + *offset_p = radeon_bo_mmap_offset(robj); > + drm_gem_object_unreference_unlocked(gobj); > + return 0; > +} > + > int radeon_mode_dumb_mmap(struct drm_file *filp, > struct drm_device *dev, > uint32_t handle, uint64_t *offset_p) > @@ -314,6 +332,14 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, > if (gobj == NULL) { > return -ENOENT; > } > + > + /* > + * We don't allow dumb mmaps on objects created using another > + * interface. > + */ > + WARN_ONCE(!(gobj->dumb || gobj->import_attach), > + "Illegal dumb map of GPU buffer.\n"); > + > robj = gem_to_radeon_bo(gobj); > *offset_p = radeon_bo_mmap_offset(robj); > drm_gem_object_unreference_unlocked(gobj); > @@ -325,7 +351,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, > { > struct drm_radeon_gem_mmap *args = data; > > - return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); > + return radeon_mode_mmap(filp, dev, args->handle, &args->addr_ptr); > } > > int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, > @@ -575,6 +601,7 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, > return -ENOMEM; > > r = drm_gem_handle_create(file_priv, gobj, &handle); > + gobj->dumb = true; > /* drop reference from allocate - handle holds it now */ > drm_gem_object_unreference_unlocked(gobj); > if (r) { > diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c > index 480c87d..1450ea0 100644 > --- a/drivers/gpu/drm/radeon/radeon_object.c > +++ b/drivers/gpu/drm/radeon/radeon_object.c > @@ -471,6 +471,9 @@ int radeon_bo_list_validate(struct radeon_device *rdev, > u32 current_domain = > radeon_mem_type_to_domain(bo->tbo.mem.mem_type); > > + WARN_ONCE(bo->gem_base.dumb, > + "GPU use of dumb buffer is illegal.\n"); > + > /* Check if this buffer will be moved and don't move it > * if we have moved too many buffers for this IB already. > * > diff --git a/include/drm/drmP.h b/include/drm/drmP.h > index 1968907..3d7908e 100644 > --- a/include/drm/drmP.h > +++ b/include/drm/drmP.h > @@ -640,6 +640,13 @@ struct drm_gem_object { > * simply leave it as NULL. > */ > struct dma_buf_attachment *import_attach; > + > + /** > + * dumb - created as dumb buffer > + * Whether the gem object was created using the dumb buffer interface > + * as such it may not be used for GPU rendering. > + */ > + bool dumb; > }; > > #include <drm/drm_crtc.h> _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel