c40b77c9575c59d7288c2b3e0871a40fb70a3698
[openwrt/staging/ansuel.git] /
1 From a984fda6b2c24dbf1ca21924f99c8f9418f5765e Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Wed, 22 Nov 2023 19:17:44 +0000
4 Subject: [PATCH] drm: vc4: Block swiotlb bounce buffers being imported as
5 dmabuf
6
7 The dmabuf import already checks that the backing buffer is contiguous
8 and rejects it if it isn't. vc4 also requires that the buffer is
9 in the bottom 1GB of RAM, and this is all correctly defined via
10 dma-ranges.
11
12 However the kernel silently uses swiotlb to bounce dma buffers
13 around if they are in the wrong region. This relies on dma sync
14 functions to be called in order to copy the data to/from the
15 bounce buffer.
16
17 DRM is based on all memory allocations being coherent with the
18 GPU so that any updates to a framebuffer will be acted on without
19 the need for any additional update. This is fairly fundamentally
20 incompatible with needing to call dma_sync_ to handle the bounce
21 buffer copies, and therefore we have to detect and reject mappings
22 that use bounce buffers.
23
24 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
25 ---
26 drivers/gpu/drm/vc4/vc4_drv.c | 26 ++++++++++++++++++++++++--
27 1 file changed, 24 insertions(+), 2 deletions(-)
28
29 --- a/drivers/gpu/drm/vc4/vc4_drv.c
30 +++ b/drivers/gpu/drm/vc4/vc4_drv.c
31 @@ -29,6 +29,7 @@
32 #include <linux/of_platform.h>
33 #include <linux/platform_device.h>
34 #include <linux/pm_runtime.h>
35 +#include <linux/dma-direct.h>
36
37 #include <drm/drm_aperture.h>
38 #include <drm/drm_atomic_helper.h>
39 @@ -175,6 +176,19 @@ static void vc4_close(struct drm_device
40 kfree(vc4file);
41 }
42
43 +struct drm_gem_object *
44 +vc4_prime_import_sg_table(struct drm_device *dev,
45 + struct dma_buf_attachment *attach,
46 + struct sg_table *sgt)
47 +{
48 + phys_addr_t phys = dma_to_phys(dev->dev, sg_dma_address(sgt->sgl));
49 +
50 + if (is_swiotlb_buffer(dev->dev, phys))
51 + return ERR_PTR(-EINVAL);
52 +
53 + return drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
54 +}
55 +
56 DEFINE_DRM_GEM_FOPS(vc4_drm_fops);
57
58 static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
59 @@ -211,7 +225,11 @@ const struct drm_driver vc4_drm_driver =
60
61 .gem_create_object = vc4_create_object,
62
63 - DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create),
64 + .dumb_create = vc4_bo_dumb_create,
65 + .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
66 + .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
67 + .gem_prime_import_sg_table = vc4_prime_import_sg_table,
68 + .gem_prime_mmap = drm_gem_prime_mmap,
69
70 .ioctls = vc4_drm_ioctls,
71 .num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
72 @@ -234,7 +252,11 @@ const struct drm_driver vc5_drm_driver =
73 .debugfs_init = vc4_debugfs_init,
74 #endif
75
76 - DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create),
77 + .dumb_create = vc5_dumb_create,
78 + .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
79 + .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
80 + .gem_prime_import_sg_table = vc4_prime_import_sg_table,
81 + .gem_prime_mmap = drm_gem_prime_mmap,
82
83 .fops = &vc4_drm_fops,
84