From nobody Fri Sep 20 14:39:56 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B455EEB580 for ; Mon, 11 Sep 2023 02:33:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233162AbjIKCdJ (ORCPT ); Sun, 10 Sep 2023 22:33:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230007AbjIKCdD (ORCPT ); Sun, 10 Sep 2023 22:33:03 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1177BCD5; Sun, 10 Sep 2023 19:32:19 -0700 (PDT) X-UUID: 6428c00e504b11ee8051498923ad61e6-20230911 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=k7eKKqiU9u1VTQEhbL4g+T+8Z/Im5zTAmaqVcrzlJog=; b=oKAqoGGgHnTwU2Nrzr77Lv7TzaetUwm2zBYVB2mGQH8flZ/fZGDLB2cPKgwRMRTzdzgWxH2poaxG79v5uQ+IVM6mcX2FUiQzRvCQ1UbaPN7RiFQij01a502CP/yNilRPd3s/shqR3mVWpLZ9o4FqblhdHwlWX2yZpexGuDIZUqw=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.31,REQID:2b9c6210-8e26-4923-9451-89365963a96c,IP:0,U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:0ad78a4,CLOUDID:dc85c713-4929-4845-9571-38c601e9c3c9,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR:NO, DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-UUID: 6428c00e504b11ee8051498923ad61e6-20230911 Received: from mtkmbs10n2.mediatek.inc [(172.21.101.183)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 650081513; Mon, 11 Sep 2023 10:32:02 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.194) by MTKMBS14N2.mediatek.inc (172.21.101.76) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Mon, 11 Sep 2023 10:32:01 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Mon, 11 Sep 2023 10:32:00 +0800 From: Yong Wu To: Rob Herring , Sumit Semwal , , Matthias Brugger CC: Krzysztof Kozlowski , Conor Dooley , Benjamin Gaignard , Brian Starkey , John Stultz , , AngeloGioacchino Del Regno , Yong Wu , , , , , , , , , Subject: [PATCH 9/9] dma_buf: heaps: mtk_sec_heap: Add a new CMA heap Date: Mon, 11 Sep 2023 10:30:38 +0800 Message-ID: <20230911023038.30649-10-yong.wu@mediatek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230911023038.30649-1-yong.wu@mediatek.com> References: <20230911023038.30649-1-yong.wu@mediatek.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-Product-Ver: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-AS-Result: No-10--7.150000-8.000000 X-TMASE-MatchedRID: l/nE+SiO7Ibv9W9IPgV+ekKcYi5Qw/RVJNtuyL6mpIWgaf0+XUrNk6jp YrigUiQ3RgA/t103tXOp3RVRr+fKXKawq2pdPD7UA9lly13c/gG94JvJnfFrHg6QlBHhBZuwYXo 6e6cMykyCrhXL3UcSds/8MSwnHgK56fubsV+A+k+yntSjDrb64SQwGQSJ46NmXCmcAC8DBrPrio 8O85DXBtuU0Ipyd28f+kFR4g8YiAE/eX/eRWk3RZA6S0SjvcYUmyqQJWNsukna+IH8mvgPVEttN R/47hK8ALglGcpZqpxRomVnnmsja5e/bF1ays2S4RtSDjG+z7BzijlDBYeD/Jsoi2XrUn/Jn6Kd MrRsL14qtq5d3cxkNTx61AcxE5RmHl89tzhQNcPdxB32r2oE1NRT50T+gtKLgL5DmE5InGnToZA 9tPKpDJ6oP1a0mRIj X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--7.150000-8.000000 X-TMASE-Version: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-SNTS-SMTP: D012446BA56B603C0A9C42A245B2817DF015B66332AAB4883A6336DF0FC547C72000:8 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Create a new mtk_svp_cma heap from the CMA reserved buffer. When the first allocating buffer, use cma_alloc to prepare whole the CMA range, then send its range to TEE to protect and manage. For the later allocating, we just adds the cma_used_size. When SVP done, cma_release will release the buffer, then kernel may reuse it. Signed-off-by: Yong Wu --- drivers/dma-buf/heaps/Kconfig | 2 +- drivers/dma-buf/heaps/mtk_secure_heap.c | 121 +++++++++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index 729c0cf3eb7c..e101f788ecbf 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -15,7 +15,7 @@ config DMABUF_HEAPS_CMA =20 config DMABUF_HEAPS_MTK_SECURE bool "DMA-BUF MediaTek Secure Heap" - depends on DMABUF_HEAPS && TEE + depends on DMABUF_HEAPS && TEE && CMA help Choose this option to enable dma-buf MediaTek secure heap for Secure Video Path. This heap is backed by TEE client interfaces. If in diff --git a/drivers/dma-buf/heaps/mtk_secure_heap.c b/drivers/dma-buf/heap= s/mtk_secure_heap.c index daf6cf2121a1..3f568fe6b569 100644 --- a/drivers/dma-buf/heaps/mtk_secure_heap.c +++ b/drivers/dma-buf/heaps/mtk_secure_heap.c @@ -4,11 +4,12 @@ * * Copyright (C) 2023 MediaTek Inc. */ - +#include #include #include #include #include +#include #include #include #include @@ -25,9 +26,11 @@ * MediaTek secure (chunk) memory type * * @KREE_MEM_SEC_CM_TZ: static chunk memory carved out for trustzone. + * @KREE_MEM_SEC_CM_CMA: dynamic chunk memory carved out from CMA. */ enum kree_mem_type { KREE_MEM_SEC_CM_TZ =3D 1, + KREE_MEM_SEC_CM_CMA, }; =20 struct mtk_secure_heap_buffer { @@ -42,6 +45,13 @@ struct mtk_secure_heap { const enum kree_mem_type mem_type; u32 mem_session; struct tee_context *tee_ctx; + + struct cma *cma; + struct page *cma_page; + unsigned long cma_paddr; + unsigned long cma_size; + unsigned long cma_used_size; + struct mutex lock; /* lock for cma_used_size */ }; =20 struct mtk_secure_heap_attachment { @@ -90,6 +100,42 @@ static int mtk_kree_secure_session_init(struct mtk_secu= re_heap *sec_heap) return ret; } =20 +static int mtk_sec_mem_cma_allocate(struct mtk_secure_heap *sec_heap, size= _t size) +{ + /* + * Allocate CMA only when allocating buffer for the first time, and just + * increase cma_used_size at the other times. + */ + mutex_lock(&sec_heap->lock); + if (sec_heap->cma_used_size) + goto add_size; + + mutex_unlock(&sec_heap->lock); + sec_heap->cma_page =3D cma_alloc(sec_heap->cma, sec_heap->cma_size >> PAG= E_SHIFT, + get_order(PAGE_SIZE), false); + if (!sec_heap->cma_page) + return -ENOMEM; + + mutex_lock(&sec_heap->lock); +add_size: + sec_heap->cma_used_size +=3D size; + mutex_unlock(&sec_heap->lock); + return sec_heap->cma_used_size; +} + +static void mtk_sec_mem_cma_free(struct mtk_secure_heap *sec_heap, size_t = size) +{ + bool cma_is_empty; + + mutex_lock(&sec_heap->lock); + sec_heap->cma_used_size -=3D size; + cma_is_empty =3D !sec_heap->cma_used_size; + mutex_unlock(&sec_heap->lock); + + if (cma_is_empty) + cma_release(sec_heap->cma, sec_heap->cma_page, sec_heap->cma_size >> PAG= E_SHIFT); +} + static int mtk_sec_mem_tee_service_call(struct tee_context *tee_ctx, u32 session, unsigned int command, struct tee_param *params) @@ -114,23 +160,47 @@ static int mtk_sec_mem_allocate(struct mtk_secure_hea= p *sec_heap, { struct tee_param params[MTK_TEE_PARAM_NUM] =3D {0}; u32 mem_session =3D sec_heap->mem_session; + bool cma_frst_alloc =3D false; int ret; =20 + if (sec_heap->cma) { + ret =3D mtk_sec_mem_cma_allocate(sec_heap, sec_buf->size); + if (ret < 0) + return ret; + /* + * When CMA allocates for the first time, pass the CMA range to TEE + * to protect it. It's the first allocating if the cma_used_size is equal + * to this required buffer size. + */ + cma_frst_alloc =3D (ret =3D=3D sec_buf->size); + } + params[0].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; params[0].u.value.a =3D SZ_4K; /* alignment */ params[0].u.value.b =3D sec_heap->mem_type; /* memory type */ params[1].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; params[1].u.value.a =3D sec_buf->size; params[2].attr =3D TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; + if (sec_heap->cma && cma_frst_alloc) { + params[2].u.value.a =3D sec_heap->cma_paddr; + params[2].u.value.b =3D sec_heap->cma_size; + } =20 /* Always request zeroed buffer */ ret =3D mtk_sec_mem_tee_service_call(sec_heap->tee_ctx, mem_session, TZCMD_MEM_SECURECM_ZALLOC, params); - if (ret) - return -ENOMEM; + if (ret) { + ret =3D -ENOMEM; + goto free_cma; + } =20 sec_buf->sec_handle =3D params[2].u.value.a; return 0; + +free_cma: + if (sec_heap->cma) + mtk_sec_mem_cma_free(sec_heap, sec_buf->size); + return ret; } =20 static void mtk_sec_mem_release(struct mtk_secure_heap *sec_heap, @@ -145,6 +215,9 @@ static void mtk_sec_mem_release(struct mtk_secure_heap = *sec_heap, =20 mtk_sec_mem_tee_service_call(sec_heap->tee_ctx, mem_session, TZCMD_MEM_SECURECM_UNREF, params); + + if (sec_heap->cma) + mtk_sec_mem_cma_free(sec_heap, sec_buf->size); } =20 static int mtk_sec_heap_attach(struct dma_buf *dmabuf, struct dma_buf_atta= chment *attachment) @@ -317,8 +390,41 @@ static struct mtk_secure_heap mtk_sec_heap[] =3D { .name =3D "mtk_svp", .mem_type =3D KREE_MEM_SEC_CM_TZ, }, + { + .name =3D "mtk_svp_cma", + .mem_type =3D KREE_MEM_SEC_CM_CMA, + }, }; =20 +static int __init mtk_secure_cma_init(struct reserved_mem *rmem) +{ + struct mtk_secure_heap *sec_heap =3D NULL; + int ret, i; + + for (i =3D 0; i < ARRAY_SIZE(mtk_sec_heap); i++) { + if (mtk_sec_heap[i].mem_type !=3D KREE_MEM_SEC_CM_CMA) + continue; + sec_heap =3D &mtk_sec_heap[i]; + break; + } + if (!sec_heap) + return -ENOENT; + + ret =3D cma_init_reserved_mem(rmem->base, rmem->size, 0, sec_heap->name, + &sec_heap->cma); + if (ret) { + pr_err("%s: %s set up CMA fail\n", __func__, rmem->name); + return ret; + } + sec_heap->cma_paddr =3D rmem->base; + sec_heap->cma_size =3D rmem->size; + + return 0; +} + +RESERVEDMEM_OF_DECLARE(mtk_secure_cma, "mediatek,secure_cma_chunkmem", + mtk_secure_cma_init); + static int mtk_sec_heap_init(void) { struct mtk_secure_heap *sec_heap =3D mtk_sec_heap; @@ -331,6 +437,15 @@ static int mtk_sec_heap_init(void) exp_info.ops =3D &mtk_sec_heap_ops; exp_info.priv =3D (void *)sec_heap; =20 + if (sec_heap->mem_type =3D=3D KREE_MEM_SEC_CM_CMA) { + if (!sec_heap->cma) { + pr_err("CMA is not ready for %s.\n", sec_heap->name); + continue; + } else { + mutex_init(&sec_heap->lock); + } + } + heap =3D dma_heap_add(&exp_info); if (IS_ERR(heap)) return PTR_ERR(heap); --=20 2.25.1