Skip to content

Commit a984fda

Browse files
6by9pelwell
authored andcommitted
drm: vc4: Block swiotlb bounce buffers being imported as dmabuf
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 <dave.stevenson@raspberrypi.com>
1 parent a420bbd commit a984fda

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

drivers/gpu/drm/vc4/vc4_drv.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <linux/of_platform.h>
3030
#include <linux/platform_device.h>
3131
#include <linux/pm_runtime.h>
32+
#include <linux/dma-direct.h>
3233

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

179+
struct drm_gem_object *
180+
vc4_prime_import_sg_table(struct drm_device *dev,
181+
struct dma_buf_attachment *attach,
182+
struct sg_table *sgt)
183+
{
184+
phys_addr_t phys = dma_to_phys(dev->dev, sg_dma_address(sgt->sgl));
185+
186+
if (is_swiotlb_buffer(dev->dev, phys))
187+
return ERR_PTR(-EINVAL);
188+
189+
return drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
190+
}
191+
178192
DEFINE_DRM_GEM_FOPS(vc4_drm_fops);
179193

180194
static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
@@ -211,7 +225,11 @@ const struct drm_driver vc4_drm_driver = {
211225

212226
.gem_create_object = vc4_create_object,
213227

214-
DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create),
228+
.dumb_create = vc4_bo_dumb_create,
229+
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
230+
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
231+
.gem_prime_import_sg_table = vc4_prime_import_sg_table,
232+
.gem_prime_mmap = drm_gem_prime_mmap,
215233

216234
.ioctls = vc4_drm_ioctls,
217235
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
@@ -234,7 +252,11 @@ const struct drm_driver vc5_drm_driver = {
234252
.debugfs_init = vc4_debugfs_init,
235253
#endif
236254

237-
DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create),
255+
.dumb_create = vc5_dumb_create,
256+
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
257+
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
258+
.gem_prime_import_sg_table = vc4_prime_import_sg_table,
259+
.gem_prime_mmap = drm_gem_prime_mmap,
238260

239261
.fops = &vc4_drm_fops,
240262

0 commit comments

Comments
 (0)