mediatek: Allocate secure buffer by DMA_HEAP_IOCTL_ALLOC

1. Allocate secure buffer from DMA_HEAP_IOCTL_ALLOC ,then using FD to
create a GEM handle and close this FD.

2. Since the secure buffer doesn't allocate via DRM_IOCTL_MTK_GEM_CREATE,
the DRM_MTK_GEM_CREATE_FLAG_RESTRICTED flag can be removed.
It should be added in the code that calls drmModeAddFB2().

3. Add mediatek_private_drv_data to store the dma_heap_fd in drv->priv,
and also add mediatek_close() to close dma_heap_fd and free drv->priv
when backend driver is closing.

BUG=b:248609774
TEST=emerge-geralt minigbm

Change-Id: I96df25580efe04f2c9a739b2d68de8837df091df
Signed-off-by: Jason-jh Lin <jason-jh.lin@mediatek.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/5581571
Reviewed-by: Jeffrey Kardatzke <jkardatzke@google.com>
Commit-Queue: Jeffrey Kardatzke <jkardatzke@google.com>
This commit is contained in:
Jason-jh Lin 2024-05-29 11:55:27 +08:00 committed by Chromeos LUCI
parent cd5aef63a7
commit 661992dfdf

View file

@ -10,9 +10,13 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#if !defined(ANDROID) || (ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP))
#include <linux/dma-heap.h>
#endif
#include <poll.h> #include <poll.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include <xf86drm.h> #include <xf86drm.h>
@ -67,6 +71,10 @@
#define USE_EXTRA_PADDING_FOR_YVU420 #define USE_EXTRA_PADDING_FOR_YVU420
#endif #endif
struct mediatek_private_drv_data {
int dma_heap_fd;
};
struct mediatek_private_map_data { struct mediatek_private_map_data {
void *cached_addr; void *cached_addr;
void *gem_addr; void *gem_addr;
@ -120,6 +128,16 @@ static bool is_video_yuv_format(uint32_t format)
static int mediatek_init(struct driver *drv) static int mediatek_init(struct driver *drv)
{ {
struct format_metadata metadata; struct format_metadata metadata;
struct mediatek_private_drv_data *priv;
priv = calloc(1, sizeof(*priv));
if (!priv) {
drv_loge("Failed calloc private data, errno=%d\n", -errno);
return -errno;
}
priv->dma_heap_fd = -1;
drv->priv = priv;
drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats), drv_add_combinations(drv, render_target_formats, ARRAY_SIZE(render_target_formats),
&LINEAR_METADATA, &LINEAR_METADATA,
@ -199,6 +217,17 @@ static int mediatek_init(struct driver *drv)
return drv_modify_linear_combinations(drv); return drv_modify_linear_combinations(drv);
} }
static void mediatek_close(struct driver *drv)
{
struct mediatek_private_drv_data *priv = (struct mediatek_private_drv_data *)drv->priv;
if (priv->dma_heap_fd >= 0)
close(priv->dma_heap_fd);
free(priv);
drv->priv = NULL;
}
static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height, static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint32_t height,
uint32_t format, const uint64_t *modifiers, uint32_t format, const uint64_t *modifiers,
uint32_t count) uint32_t count)
@ -329,8 +358,16 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
#endif #endif
} }
/* For protected data buffer needs to be allocated from GEM */ /* For protected data buffer needs to allocate from DMA_HEAP directly */
if (is_protected) { if (is_protected) {
#if !defined(ANDROID) || (ANDROID_API_LEVEL >= 31 && defined(HAS_DMABUF_SYSTEM_HEAP))
int ret;
struct mediatek_private_drv_data *priv = (struct mediatek_private_drv_data *)bo->drv->priv;
struct dma_heap_allocation_data heap_data = {
.len = bo->meta.total_size,
.fd_flags = O_RDWR | O_CLOEXEC,
};
if (format == DRM_FORMAT_P010) { if (format == DRM_FORMAT_P010) {
/* /*
* Adjust the size so we don't waste tons of space. This was allocated * Adjust the size so we don't waste tons of space. This was allocated
@ -344,7 +381,33 @@ static int mediatek_bo_create_with_modifiers(struct bo *bo, uint32_t width, uint
bo->meta.offsets[1] = bo->meta.sizes[0]; bo->meta.offsets[1] = bo->meta.sizes[0];
bo->meta.total_size = bo->meta.total_size * 10 / 16; bo->meta.total_size = bo->meta.total_size * 10 / 16;
} }
gem_create.flags |= DRM_MTK_GEM_CREATE_FLAG_RESTRICTED;
if (priv->dma_heap_fd < 0) {
priv->dma_heap_fd = open("/dev/dma_heap/restricted_mtk_cma", O_RDWR | O_CLOEXEC);
if (priv->dma_heap_fd < 0) {
drv_loge("Failed opening secure CMA heap errno=%d\n", -errno);
return -errno;
}
}
ret = ioctl(priv->dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data);
if (ret < 0) {
drv_loge("Failed allocating CMA buffer ret=%d\n", ret);
return ret;
}
/* Create GEM handle for secure CMA and close FD here */
ret = drmPrimeFDToHandle(bo->drv->fd, heap_data.fd, &bo->handle.u32);
close(heap_data.fd);
if (ret) {
drv_loge("Failed drmPrimeFDToHandle(fd:%d) ret=%d\n", heap_data.fd, ret);
return ret;
}
#else
drv_loge("Protected allocation not supported\n");
return -1;
#endif
return 0;
} }
/* /*
@ -559,6 +622,7 @@ static void mediatek_resolve_format_and_use_flags(struct driver *drv, uint32_t f
const struct backend backend_mediatek = { const struct backend backend_mediatek = {
.name = "mediatek", .name = "mediatek",
.init = mediatek_init, .init = mediatek_init,
.close = mediatek_close,
.bo_create = mediatek_bo_create, .bo_create = mediatek_bo_create,
.bo_create_with_modifiers = mediatek_bo_create_with_modifiers, .bo_create_with_modifiers = mediatek_bo_create_with_modifiers,
.bo_destroy = drv_gem_bo_destroy, .bo_destroy = drv_gem_bo_destroy,