Skip to content

Commit

Permalink
drm: vc4: Block swiotlb bounce buffers being imported as dmabuf
Browse files Browse the repository at this point in the history
The dmabuf import already checks that the backing buffer is contiguous
and rejects it if it isn't. vc4 also requires that the buffer is
in the bottom 1GB of RAM, and this is all correctly defined via
dma-ranges.

However the kernel silently uses swiotlb to bounce dma buffers
around if they are in the wrong region. This relies on dma sync
functions to be called in order to copy the data to/from the
bounce buffer.

DRM is based on all memory allocations being coherent with the
GPU so that any updates to a framebuffer will be acted on without
the need for any additional update. This is fairly fundamentally
incompatible with needing to call dma_sync_ to handle the bounce
buffer copies, and therefore we have to detect and reject mappings
that use bounce buffers.

Signed-off-by: Dave Stevenson <[email protected]>
  • Loading branch information
6by9 authored and pelwell committed Nov 23, 2023
1 parent a420bbd commit a984fda
Showing 1 changed file with 24 additions and 2 deletions.
26 changes: 24 additions & 2 deletions drivers/gpu/drm/vc4/vc4_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/dma-direct.h>

#include <drm/drm_aperture.h>
#include <drm/drm_atomic_helper.h>
Expand Down Expand Up @@ -175,6 +176,19 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file)
kfree(vc4file);
}

struct drm_gem_object *
vc4_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,
struct sg_table *sgt)
{
phys_addr_t phys = dma_to_phys(dev->dev, sg_dma_address(sgt->sgl));

if (is_swiotlb_buffer(dev->dev, phys))
return ERR_PTR(-EINVAL);

return drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
}

DEFINE_DRM_GEM_FOPS(vc4_drm_fops);

static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
Expand Down Expand Up @@ -211,7 +225,11 @@ const struct drm_driver vc4_drm_driver = {

.gem_create_object = vc4_create_object,

DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create),
.dumb_create = vc4_bo_dumb_create,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import_sg_table = vc4_prime_import_sg_table,
.gem_prime_mmap = drm_gem_prime_mmap,

.ioctls = vc4_drm_ioctls,
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
Expand All @@ -234,7 +252,11 @@ const struct drm_driver vc5_drm_driver = {
.debugfs_init = vc4_debugfs_init,
#endif

DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create),
.dumb_create = vc5_dumb_create,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import_sg_table = vc4_prime_import_sg_table,
.gem_prime_mmap = drm_gem_prime_mmap,

.fops = &vc4_drm_fops,

Expand Down

0 comments on commit a984fda

Please sign in to comment.