[PATCH v5 7/9] dma-buf: heaps: restricted_heap: Add MediaTek restricted heap and heap_init

Jens Wiklander jens.wiklander at linaro.org
Thu Aug 22 15:11:57 UTC 2024


On Wed, May 15, 2024 at 1:25 PM Yong Wu <yong.wu at mediatek.com> wrote:
>
> Add a MediaTek restricted heap which uses TEE service call to restrict
> buffer. Currently this restricted heap is NULL, Prepare for the later
> patch. Mainly there are two changes:
> a) Add a heap_init ops since TEE probe late than restricted heap, thus
>    initialize the heap when we require the buffer the first time.
> b) Add a priv_data for each heap, like the special data used by MTK
>    (such as "TEE session") can be placed in priv_data.
>
> Currently our heap depends on CMA which could only be bool, thus
> depend on "TEE=y".
>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  drivers/dma-buf/heaps/Kconfig               |   7 ++
>  drivers/dma-buf/heaps/Makefile              |   1 +
>  drivers/dma-buf/heaps/restricted_heap.c     |  11 ++
>  drivers/dma-buf/heaps/restricted_heap.h     |   2 +
>  drivers/dma-buf/heaps/restricted_heap_mtk.c | 115 ++++++++++++++++++++
>  5 files changed, 136 insertions(+)
>  create mode 100644 drivers/dma-buf/heaps/restricted_heap_mtk.c
>
> diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
> index e54506f480ea..84f748fb2856 100644
> --- a/drivers/dma-buf/heaps/Kconfig
> +++ b/drivers/dma-buf/heaps/Kconfig
> @@ -21,3 +21,10 @@ config DMABUF_HEAPS_RESTRICTED
>           heap is to manage buffers that are inaccessible to the kernel and user space.
>           There may be several ways to restrict it, for example it may be encrypted or
>           protected by a TEE or hypervisor. If in doubt, say N.
> +
> +config DMABUF_HEAPS_RESTRICTED_MTK
> +       bool "MediaTek DMA-BUF Restricted Heap"
> +       depends on DMABUF_HEAPS_RESTRICTED && TEE=y
> +       help
> +         Enable restricted dma-buf heaps for MediaTek platform. This heap is backed by
> +         TEE client interfaces. If in doubt, say N.
> diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile
> index a2437c1817e2..0028aa9d875f 100644
> --- a/drivers/dma-buf/heaps/Makefile
> +++ b/drivers/dma-buf/heaps/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_DMABUF_HEAPS_CMA)         += cma_heap.o
>  obj-$(CONFIG_DMABUF_HEAPS_RESTRICTED)  += restricted_heap.o
> +obj-$(CONFIG_DMABUF_HEAPS_RESTRICTED_MTK)      += restricted_heap_mtk.o
>  obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)      += system_heap.o
> diff --git a/drivers/dma-buf/heaps/restricted_heap.c b/drivers/dma-buf/heaps/restricted_heap.c
> index 4e45d46a6467..8bc8a5e3f969 100644
> --- a/drivers/dma-buf/heaps/restricted_heap.c
> +++ b/drivers/dma-buf/heaps/restricted_heap.c
> @@ -151,11 +151,22 @@ restricted_heap_allocate(struct dma_heap *heap, unsigned long size,
>                          unsigned long fd_flags, unsigned long heap_flags)
>  {
>         struct restricted_heap *rheap = dma_heap_get_drvdata(heap);
> +       const struct restricted_heap_ops *ops = rheap->ops;
>         struct restricted_buffer *restricted_buf;
>         DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
>         struct dma_buf *dmabuf;
>         int ret;
>
> +       /*
> +        * In some implements, TEE is required to protect buffer. However TEE probe
> +        * may be late, Thus heap_init is performed when the first buffer is requested.
> +        */
> +       if (ops->heap_init) {
> +               ret = ops->heap_init(rheap);
> +               if (ret)
> +                       return ERR_PTR(ret);
> +       }
> +
>         restricted_buf = kzalloc(sizeof(*restricted_buf), GFP_KERNEL);
>         if (!restricted_buf)
>                 return ERR_PTR(-ENOMEM);
> diff --git a/drivers/dma-buf/heaps/restricted_heap.h b/drivers/dma-buf/heaps/restricted_heap.h
> index 6d9599a4a34e..2a33a1c7a48b 100644
> --- a/drivers/dma-buf/heaps/restricted_heap.h
> +++ b/drivers/dma-buf/heaps/restricted_heap.h
> @@ -19,6 +19,8 @@ struct restricted_heap {
>         const char              *name;
>
>         const struct restricted_heap_ops *ops;
> +
> +       void                    *priv_data;
>  };
>
>  struct restricted_heap_ops {
> diff --git a/drivers/dma-buf/heaps/restricted_heap_mtk.c b/drivers/dma-buf/heaps/restricted_heap_mtk.c
> new file mode 100644
> index 000000000000..52e805eb9858
> --- /dev/null
> +++ b/drivers/dma-buf/heaps/restricted_heap_mtk.c
> @@ -0,0 +1,115 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * DMABUF restricted heap exporter for MediaTek
> + *
> + * Copyright (C) 2024 MediaTek Inc.
> + */
> +#define pr_fmt(fmt)     "rheap_mtk: " fmt
> +
> +#include <linux/dma-buf.h>
> +#include <linux/err.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/tee_drv.h>
> +#include <linux/uuid.h>
> +
> +#include "restricted_heap.h"
> +
> +#define TZ_TA_MEM_UUID_MTK             "4477588a-8476-11e2-ad15-e41f1390d676"
> +
> +#define TEE_PARAM_NUM                  4
> +
> +enum mtk_secure_mem_type {
> +       /*
> +        * MediaTek static chunk memory carved out for TrustZone. The memory
> +        * management is inside the TEE.
> +        */
> +       MTK_SECURE_MEMORY_TYPE_CM_TZ    = 1,
> +};
> +
> +struct mtk_restricted_heap_data {
> +       struct tee_context      *tee_ctx;
> +       u32                     tee_session;
> +
> +       const enum mtk_secure_mem_type mem_type;
> +
> +};
> +
> +static int mtk_tee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
> +{
> +       return ver->impl_id == TEE_IMPL_ID_OPTEE;
> +}
> +
> +static int mtk_tee_session_init(struct mtk_restricted_heap_data *data)
> +{
> +       struct tee_param t_param[TEE_PARAM_NUM] = {0};
> +       struct tee_ioctl_open_session_arg arg = {0};
> +       uuid_t ta_mem_uuid;
> +       int ret;
> +
> +       data->tee_ctx = tee_client_open_context(NULL, mtk_tee_ctx_match, NULL, NULL);
> +       if (IS_ERR(data->tee_ctx)) {
> +               pr_err_once("%s: open context failed, ret=%ld\n", __func__,
> +                           PTR_ERR(data->tee_ctx));
> +               return -ENODEV;
> +       }
> +
> +       arg.num_params = TEE_PARAM_NUM;
> +       arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
> +       ret = uuid_parse(TZ_TA_MEM_UUID_MTK, &ta_mem_uuid);
> +       if (ret)
> +               goto close_context;
> +       memcpy(&arg.uuid, &ta_mem_uuid.b, sizeof(ta_mem_uuid));
> +
> +       ret = tee_client_open_session(data->tee_ctx, &arg, t_param);
> +       if (ret < 0 || arg.ret) {
> +               pr_err_once("%s: open session failed, ret=%d:%d\n",
> +                           __func__, ret, arg.ret);
> +               ret = -EINVAL;
> +               goto close_context;
> +       }
> +       data->tee_session = arg.session;
> +       return 0;
> +
> +close_context:
> +       tee_client_close_context(data->tee_ctx);

There's a
data->tee_ctx = NULL;
missing here.

Cheers,
Jens

> +       return ret;
> +}
> +
> +static int mtk_restricted_heap_init(struct restricted_heap *rheap)
> +{
> +       struct mtk_restricted_heap_data *data = rheap->priv_data;
> +
> +       if (!data->tee_ctx)
> +               return mtk_tee_session_init(data);
> +       return 0;
> +}
> +
> +static const struct restricted_heap_ops mtk_restricted_heap_ops = {
> +       .heap_init              = mtk_restricted_heap_init,
> +};
> +
> +static struct mtk_restricted_heap_data mtk_restricted_heap_data = {
> +       .mem_type               = MTK_SECURE_MEMORY_TYPE_CM_TZ,
> +};
> +
> +static struct restricted_heap mtk_restricted_heaps[] = {
> +       {
> +               .name           = "restricted_mtk_cm",
> +               .ops            = &mtk_restricted_heap_ops,
> +               .priv_data      = &mtk_restricted_heap_data,
> +       },
> +};
> +
> +static int mtk_restricted_heap_initialize(void)
> +{
> +       struct restricted_heap *rheap = mtk_restricted_heaps;
> +       unsigned int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(mtk_restricted_heaps); i++, rheap++)
> +               restricted_heap_add(rheap);
> +       return 0;
> +}
> +module_init(mtk_restricted_heap_initialize);
> +MODULE_DESCRIPTION("MediaTek Restricted Heap Driver");
> +MODULE_LICENSE("GPL");
> --
> 2.25.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


More information about the dri-devel mailing list