1419b0af8Sopenharmony_ci/*
2419b0af8Sopenharmony_ci * Copyright (c) 2012-2022 Huawei Technologies Co., Ltd.
3419b0af8Sopenharmony_ci * Description: dynamic Ion memory allocation and free.
4419b0af8Sopenharmony_ci *
5419b0af8Sopenharmony_ci * This software is licensed under the terms of the GNU General Public
6419b0af8Sopenharmony_ci * License version 2, as published by the Free Software Foundation, and
7419b0af8Sopenharmony_ci * may be copied, distributed, and modified under those terms.
8419b0af8Sopenharmony_ci *
9419b0af8Sopenharmony_ci * This program is distributed in the hope that it will be useful,
10419b0af8Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
11419b0af8Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12419b0af8Sopenharmony_ci * GNU General Public License for more details.
13419b0af8Sopenharmony_ci */
14419b0af8Sopenharmony_ci
15419b0af8Sopenharmony_ci#include "dynamic_ion_mem.h"
16419b0af8Sopenharmony_ci#include <linux/version.h>
17419b0af8Sopenharmony_ci#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
18419b0af8Sopenharmony_ci#include <stdarg.h>
19419b0af8Sopenharmony_ci#else
20419b0af8Sopenharmony_ci#include <linux/stdarg.h>
21419b0af8Sopenharmony_ci#endif
22419b0af8Sopenharmony_ci#include <linux/workqueue.h>
23419b0af8Sopenharmony_ci#include <linux/kthread.h>
24419b0af8Sopenharmony_ci#include <linux/list.h>
25419b0af8Sopenharmony_ci#include <linux/sched.h>
26419b0af8Sopenharmony_ci#include <linux/delay.h>
27419b0af8Sopenharmony_ci#include <linux/mutex.h>
28419b0af8Sopenharmony_ci#include <linux/timer.h>
29419b0af8Sopenharmony_ci#include <linux/kernel.h>
30419b0af8Sopenharmony_ci#include <linux/uaccess.h>
31419b0af8Sopenharmony_ci#include <linux/debugfs.h>
32419b0af8Sopenharmony_ci#include <linux/module.h>
33419b0af8Sopenharmony_ci#include <linux/version.h>
34419b0af8Sopenharmony_ci#ifndef CONFIG_DMABUF_MM
35419b0af8Sopenharmony_ci#include <linux/ion.h>
36419b0af8Sopenharmony_ci#endif
37419b0af8Sopenharmony_ci#include <linux/mm.h>
38419b0af8Sopenharmony_ci#include <linux/cma.h>
39419b0af8Sopenharmony_ci#include <asm/tlbflush.h>
40419b0af8Sopenharmony_ci#include <asm/cacheflush.h>
41419b0af8Sopenharmony_ci#if ((defined CONFIG_ION_MM) || (defined CONFIG_ION_MM_SECSG))
42419b0af8Sopenharmony_ci#include <linux/ion/mm_ion.h>
43419b0af8Sopenharmony_ci#endif
44419b0af8Sopenharmony_ci#ifdef CONFIG_DMABUF_MM
45419b0af8Sopenharmony_ci#include <linux/dmabuf/mm_dma_heap.h>
46419b0af8Sopenharmony_ci#endif
47419b0af8Sopenharmony_ci#include "tc_ns_log.h"
48419b0af8Sopenharmony_ci#include "tc_ns_client.h"
49419b0af8Sopenharmony_ci#include "smc_smp.h"
50419b0af8Sopenharmony_ci#include "gp_ops.h"
51419b0af8Sopenharmony_ci#include "teek_client_constants.h"
52419b0af8Sopenharmony_ci#include "mailbox_mempool.h"
53419b0af8Sopenharmony_ci#include "dynamic_ion_uuid.h"
54419b0af8Sopenharmony_ci
55419b0af8Sopenharmony_cistatic DEFINE_MUTEX(dynamic_mem_lock);
56419b0af8Sopenharmony_cistruct dynamic_mem_list {
57419b0af8Sopenharmony_ci	struct list_head list;
58419b0af8Sopenharmony_ci};
59419b0af8Sopenharmony_ci
60419b0af8Sopenharmony_cistatic const struct dynamic_mem_config g_dyn_mem_config[] = {
61419b0af8Sopenharmony_ci	#ifdef DEF_ENG
62419b0af8Sopenharmony_ci	{TEE_SERVICE_UT, SEC_EID},
63419b0af8Sopenharmony_ci	{TEE_SERVICE_TEST_DYNION, SEC_AI_ION},
64419b0af8Sopenharmony_ci	#endif
65419b0af8Sopenharmony_ci	{TEE_SECIDENTIFICATION1, SEC_EID},
66419b0af8Sopenharmony_ci	{TEE_SECIDENTIFICATION3, SEC_EID},
67419b0af8Sopenharmony_ci	{TEE_SERVICE_AI, SEC_AI_ION},
68419b0af8Sopenharmony_ci	{TEE_SERVICE_AI_TINY, SEC_AI_ION},
69419b0af8Sopenharmony_ci	{TEE_SERVICE_VCODEC, SEC_DRM_TEE},
70419b0af8Sopenharmony_ci};
71419b0af8Sopenharmony_ci
72419b0af8Sopenharmony_cistatic struct dynamic_mem_list g_dynamic_mem_list;
73419b0af8Sopenharmony_cistatic const uint32_t g_dyn_mem_config_num = ARRAY_SIZE(g_dyn_mem_config);
74419b0af8Sopenharmony_ci
75419b0af8Sopenharmony_cistatic int release_ion_srv(const struct tc_uuid *uuid)
76419b0af8Sopenharmony_ci{
77419b0af8Sopenharmony_ci	struct tc_ns_smc_cmd smc_cmd = {{0}, 0};
78419b0af8Sopenharmony_ci
79419b0af8Sopenharmony_ci	smc_cmd.err_origin = TEEC_ORIGIN_COMMS;
80419b0af8Sopenharmony_ci	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
81419b0af8Sopenharmony_ci	smc_cmd.cmd_id = GLOBAL_CMD_ID_RELEASE_ION_SRV;
82419b0af8Sopenharmony_ci	if (memcpy_s(&smc_cmd.uuid, sizeof(smc_cmd.uuid), uuid, sizeof(*uuid))) {
83419b0af8Sopenharmony_ci		tloge("copy uuid failed\n");
84419b0af8Sopenharmony_ci		return -ENOMEM;
85419b0af8Sopenharmony_ci	}
86419b0af8Sopenharmony_ci
87419b0af8Sopenharmony_ci	if (tc_ns_smc(&smc_cmd)) {
88419b0af8Sopenharmony_ci		tloge("send release ion srv cmd failed\n");
89419b0af8Sopenharmony_ci		return -EPERM;
90419b0af8Sopenharmony_ci	}
91419b0af8Sopenharmony_ci	return 0;
92419b0af8Sopenharmony_ci}
93419b0af8Sopenharmony_ci
94419b0af8Sopenharmony_ci
95419b0af8Sopenharmony_cistatic int get_ion_sglist(struct dynamic_mem_item *mem_item)
96419b0af8Sopenharmony_ci{
97419b0af8Sopenharmony_ci	struct sglist *tmp_sglist = NULL;
98419b0af8Sopenharmony_ci	struct scatterlist *sg = NULL;
99419b0af8Sopenharmony_ci	struct page *page = NULL;
100419b0af8Sopenharmony_ci	uint32_t sglist_size;
101419b0af8Sopenharmony_ci	uint32_t i = 0;
102419b0af8Sopenharmony_ci	struct sg_table *ion_sg_table = mem_item->memory.dyn_sg_table;
103419b0af8Sopenharmony_ci
104419b0af8Sopenharmony_ci	if (!ion_sg_table)
105419b0af8Sopenharmony_ci		return -EINVAL;
106419b0af8Sopenharmony_ci
107419b0af8Sopenharmony_ci	if (ion_sg_table->nents <= 0 || ion_sg_table->nents > MAX_ION_NENTS)
108419b0af8Sopenharmony_ci		return -EINVAL;
109419b0af8Sopenharmony_ci
110419b0af8Sopenharmony_ci	for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) {
111419b0af8Sopenharmony_ci		if (!sg) {
112419b0af8Sopenharmony_ci			tloge("an error sg when get ion sglist\n");
113419b0af8Sopenharmony_ci			return -EINVAL;
114419b0af8Sopenharmony_ci		}
115419b0af8Sopenharmony_ci	}
116419b0af8Sopenharmony_ci
117419b0af8Sopenharmony_ci	sglist_size = sizeof(struct ion_page_info) * ion_sg_table->nents + sizeof(*tmp_sglist);
118419b0af8Sopenharmony_ci	tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO);
119419b0af8Sopenharmony_ci	if (!tmp_sglist) {
120419b0af8Sopenharmony_ci		tloge("mailbox alloc failed\n");
121419b0af8Sopenharmony_ci		return -ENOMEM;
122419b0af8Sopenharmony_ci	}
123419b0af8Sopenharmony_ci
124419b0af8Sopenharmony_ci	tmp_sglist->sglist_size = (uint64_t)sglist_size;
125419b0af8Sopenharmony_ci	tmp_sglist->ion_size = (uint64_t)mem_item->size;
126419b0af8Sopenharmony_ci	tmp_sglist->info_length = (uint64_t)ion_sg_table->nents;
127419b0af8Sopenharmony_ci	for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) {
128419b0af8Sopenharmony_ci		page = sg_page(sg);
129419b0af8Sopenharmony_ci		tmp_sglist->page_info[i].phys_addr = page_to_phys(page);
130419b0af8Sopenharmony_ci		tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE;
131419b0af8Sopenharmony_ci	}
132419b0af8Sopenharmony_ci	mem_item->memory.ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_sglist);
133419b0af8Sopenharmony_ci	mem_item->memory.len = sglist_size;
134419b0af8Sopenharmony_ci	return 0;
135419b0af8Sopenharmony_ci}
136419b0af8Sopenharmony_ci
137419b0af8Sopenharmony_cistatic int send_dyn_ion_cmd(struct dynamic_mem_item *mem_item, unsigned int cmd_id, int32_t *ret_origin)
138419b0af8Sopenharmony_ci{
139419b0af8Sopenharmony_ci	struct tc_ns_smc_cmd smc_cmd = {{0}, 0};
140419b0af8Sopenharmony_ci	int ret;
141419b0af8Sopenharmony_ci	struct mb_cmd_pack *mb_pack = NULL;
142419b0af8Sopenharmony_ci
143419b0af8Sopenharmony_ci	if (!mem_item) {
144419b0af8Sopenharmony_ci		tloge("mem_item is null\n");
145419b0af8Sopenharmony_ci		return -EINVAL;
146419b0af8Sopenharmony_ci	}
147419b0af8Sopenharmony_ci
148419b0af8Sopenharmony_ci	ret = get_ion_sglist(mem_item);
149419b0af8Sopenharmony_ci	if (ret != 0)
150419b0af8Sopenharmony_ci		return ret;
151419b0af8Sopenharmony_ci
152419b0af8Sopenharmony_ci	mb_pack = mailbox_alloc_cmd_pack();
153419b0af8Sopenharmony_ci	if (!mb_pack) {
154419b0af8Sopenharmony_ci		mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr));
155419b0af8Sopenharmony_ci		tloge("alloc cmd pack failed\n");
156419b0af8Sopenharmony_ci		return -ENOMEM;
157419b0af8Sopenharmony_ci	}
158419b0af8Sopenharmony_ci	smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
159419b0af8Sopenharmony_ci	smc_cmd.cmd_id = cmd_id;
160419b0af8Sopenharmony_ci	smc_cmd.err_origin = TEEC_ORIGIN_COMMS;
161419b0af8Sopenharmony_ci	mb_pack->operation.paramtypes = teec_param_types(
162419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_ION_SGLIST_INPUT,
163419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT,
164419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_VALUE_INPUT,
165419b0af8Sopenharmony_ci		TEE_PARAM_TYPE_NONE);
166419b0af8Sopenharmony_ci
167419b0af8Sopenharmony_ci	mb_pack->operation.params[0].memref.size = (uint32_t)mem_item->memory.len;
168419b0af8Sopenharmony_ci	mb_pack->operation.params[0].memref.buffer =
169419b0af8Sopenharmony_ci	(uint32_t)(mem_item->memory.ion_phys_addr & 0xFFFFFFFF);
170419b0af8Sopenharmony_ci	mb_pack->operation.buffer_h_addr[0] =
171419b0af8Sopenharmony_ci	(uint64_t)(mem_item->memory.ion_phys_addr) >> ADDR_TRANS_NUM;
172419b0af8Sopenharmony_ci	mb_pack->operation.params[1].value.a = (uint32_t)mem_item->size;
173419b0af8Sopenharmony_ci	mb_pack->operation.params[2].value.a = mem_item->configid;
174419b0af8Sopenharmony_ci	smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
175419b0af8Sopenharmony_ci	smc_cmd.operation_h_phys = (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM;
176419b0af8Sopenharmony_ci
177419b0af8Sopenharmony_ci	if (tc_ns_smc(&smc_cmd)) {
178419b0af8Sopenharmony_ci		if (ret_origin)
179419b0af8Sopenharmony_ci			*ret_origin = smc_cmd.err_origin;
180419b0af8Sopenharmony_ci		ret = -EPERM;
181419b0af8Sopenharmony_ci		tlogd("send loadapp ion failed\n");
182419b0af8Sopenharmony_ci	}
183419b0af8Sopenharmony_ci	mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr));
184419b0af8Sopenharmony_ci	mailbox_free(mb_pack);
185419b0af8Sopenharmony_ci	return ret;
186419b0af8Sopenharmony_ci}
187419b0af8Sopenharmony_ci
188419b0af8Sopenharmony_cistatic struct dynamic_mem_item *find_memitem_by_configid_locked(uint32_t configid)
189419b0af8Sopenharmony_ci{
190419b0af8Sopenharmony_ci	struct dynamic_mem_item *item = NULL;
191419b0af8Sopenharmony_ci	list_for_each_entry(item, &g_dynamic_mem_list.list, head) {
192419b0af8Sopenharmony_ci		if (item->configid == configid)
193419b0af8Sopenharmony_ci			return item;
194419b0af8Sopenharmony_ci	}
195419b0af8Sopenharmony_ci	return NULL;
196419b0af8Sopenharmony_ci}
197419b0af8Sopenharmony_ci
198419b0af8Sopenharmony_cistatic struct dynamic_mem_item *find_memitem_by_uuid_locked(const struct tc_uuid *uuid)
199419b0af8Sopenharmony_ci{
200419b0af8Sopenharmony_ci	struct dynamic_mem_item *item = NULL;
201419b0af8Sopenharmony_ci	list_for_each_entry(item, &g_dynamic_mem_list.list, head) {
202419b0af8Sopenharmony_ci		if (!memcmp(&item->uuid, uuid, sizeof(*uuid)))
203419b0af8Sopenharmony_ci			return item;
204419b0af8Sopenharmony_ci	}
205419b0af8Sopenharmony_ci	return NULL;
206419b0af8Sopenharmony_ci}
207419b0af8Sopenharmony_ci
208419b0af8Sopenharmony_ci#define BLOCK_64KB_SIZE (64 * 1024) /* 64 */
209419b0af8Sopenharmony_ci#define BLOCK_64KB_MASK 0xFFFFFFFFFFFF0000
210419b0af8Sopenharmony_ci/* size should be aligned with 64KB */
211419b0af8Sopenharmony_ci#define BLOCK_64KB_SIZE_MASK (BLOCK_64KB_SIZE -1)
212419b0af8Sopenharmony_cistatic int proc_alloc_dyn_mem(struct dynamic_mem_item *mem_item)
213419b0af8Sopenharmony_ci{
214419b0af8Sopenharmony_ci	struct sg_table *ion_sg_table = NULL;
215419b0af8Sopenharmony_ci
216419b0af8Sopenharmony_ci	if (mem_item->size + BLOCK_64KB_SIZE_MASK < mem_item->size) {
217419b0af8Sopenharmony_ci		tloge("ion size is error, size = %x\n", mem_item->size);
218419b0af8Sopenharmony_ci		return -EINVAL;
219419b0af8Sopenharmony_ci	}
220419b0af8Sopenharmony_ci	mem_item->memory.len = (mem_item ->size + BLOCK_64KB_SIZE_MASK) & BLOCK_64KB_MASK;
221419b0af8Sopenharmony_ci
222419b0af8Sopenharmony_ci	ion_sg_table = mm_secmem_alloc(mem_item->addr_sec_region,
223419b0af8Sopenharmony_ci		mem_item->memory.len);
224419b0af8Sopenharmony_ci	if (!ion_sg_table) {
225419b0af8Sopenharmony_ci		tloge("failed to get ion page, configid = %d\n",
226419b0af8Sopenharmony_ci			mem_item->configid);
227419b0af8Sopenharmony_ci		return -ENOMEM;
228419b0af8Sopenharmony_ci	}
229419b0af8Sopenharmony_ci	mem_item->memory.dyn_sg_table = ion_sg_table;
230419b0af8Sopenharmony_ci	return 0;
231419b0af8Sopenharmony_ci}
232419b0af8Sopenharmony_ci
233419b0af8Sopenharmony_cistatic void proc_free_dyn_mem(struct dynamic_mem_item *mem_item)
234419b0af8Sopenharmony_ci{
235419b0af8Sopenharmony_ci	if (!mem_item->memory.dyn_sg_table) {
236419b0af8Sopenharmony_ci		tloge("ion_phys_addr is NULL\n");
237419b0af8Sopenharmony_ci		return;
238419b0af8Sopenharmony_ci	}
239419b0af8Sopenharmony_ci	mm_secmem_free(mem_item->ddr_sec_region,
240419b0af8Sopenharmony_ci		mem_item->memory.dyn_sg_table);
241419b0af8Sopenharmony_ci	mem_item->memory.dyn_sg_table = NULL;
242419b0af8Sopenharmony_ci	return;
243419b0af8Sopenharmony_ci}
244419b0af8Sopenharmony_ci
245419b0af8Sopenharmony_ciint init_dynamic_mem(void)
246419b0af8Sopenharmony_ci{
247419b0af8Sopenharmony_ci	INIT_LIST_HEAD(&(g_dynamic_mem_list.list));
248419b0af8Sopenharmony_ci	return 0;
249419b0af8Sopenharmony_ci}
250419b0af8Sopenharmony_ci
251419b0af8Sopenharmony_cistatic int32_t find_ddr_sec_region_by_uuid(const struct tc_uuid *uuid,
252419b0af8Sopenharmony_ci	uint32_t *ddr_sec_region)
253419b0af8Sopenharmony_ci{
254419b0af8Sopenharmony_ci	uint32_t i;
255419b0af8Sopenharmony_ci	for (i = 0; i < g_dyn_mem_config_num; i++) {
256419b0af8Sopenharmony_ci		if (!memcmp(&(g_dyn_mem_config[i].uuid), uuid,
257419b0af8Sopenharmony_ci			sizeof(*uuid))) {
258419b0af8Sopenharmony_ci			*ddr_sec_region = g_dyn_mem_config[i].ddr_sec_region;
259419b0af8Sopenharmony_ci		return 0;
260419b0af8Sopenharmony_ci		}
261419b0af8Sopenharmony_ci	}
262419b0af8Sopenharmony_ci	return -EINVAL;
263419b0af8Sopenharmony_ci}
264419b0af8Sopenharmony_ci
265419b0af8Sopenharmony_cistatic struct dynamic_mem_item *alloc_dyn_mem_item(uint32_t configid,
266419b0af8Sopenharmony_ci	uint32_t cafd, const struct tc_uuid *uuid, uint32_t size)
267419b0af8Sopenharmony_ci{
268419b0af8Sopenharmony_ci	uint32_t ddr_sec_region;
269419b0af8Sopenharmony_ci	struct dynamic_mem_item *mem_item = NULL;
270419b0af8Sopenharmony_ci	int32_t result;
271419b0af8Sopenharmony_ci
272419b0af8Sopenharmony_ci	result = find_ddr_sec_region_by_uuid(uuid, &ddr_sec_region);
273419b0af8Sopenharmony_ci	if (result != 0) {
274419b0af8Sopenharmony_ci		tloge("find ddr sec region failed\n");
275419b0af8Sopenharmony_ci		return NULL;
276419b0af8Sopenharmony_ci	}
277419b0af8Sopenharmony_ci
278419b0af8Sopenharmony_ci	mem_item = kzalloc(sizeof(*mem_item), GFP_KERNEL);
279419b0af8Sopenharmony_ci	if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)mem_item)) {
280419b0af8Sopenharmony_ci		tloge("alloc mem item failed\n");
281419b0af8Sopenharmony_ci		return NULL;
282419b0af8Sopenharmony_ci	}
283419b0af8Sopenharmony_ci
284419b0af8Sopenharmony_ci	mem_item->ddr_sec_region = ddr_sec_region;
285419b0af8Sopenharmony_ci	mem_item->configid = configid;
286419b0af8Sopenharmony_ci	mem_item->size = size;
287419b0af8Sopenharmony_ci	mem_item->cafd = cafd;
288419b0af8Sopenharmony_ci	result = memcpy_s(&mem_item->uuid, sizeof(mem_item->uuid), uuid,
289419b0af8Sopenharmony_ci		sizeof(*uuid));
290419b0af8Sopenharmony_ci	if(result != EOK) {
291419b0af8Sopenharmony_ci		tloge("memcpy uuid failed\n");
292419b0af8Sopenharmony_ci		kfree(mem_item);
293419b0af8Sopenharmony_ci		return NULL;
294419b0af8Sopenharmony_ci	}
295419b0af8Sopenharmony_ci	return mem_item;
296419b0af8Sopenharmony_ci}
297419b0af8Sopenharmony_ci
298419b0af8Sopenharmony_ci
299419b0af8Sopenharmony_cistatic int trans_configid2memid(uint32_t configid, uint32_t cafd,
300419b0af8Sopenharmony_ci	const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin)
301419b0af8Sopenharmony_ci{
302419b0af8Sopenharmony_ci	int result;
303419b0af8Sopenharmony_ci
304419b0af8Sopenharmony_ci	if (!uuid)
305419b0af8Sopenharmony_ci		return -EINVAL;
306419b0af8Sopenharmony_ci	mutex_lock(&dynamic_mem_lock);
307419b0af8Sopenharmony_ci	do {
308419b0af8Sopenharmony_ci		struct dynamic_mem_item *mem_item =
309419b0af8Sopenharmony_ci		find_memitem_by_configid_locked(configid);
310419b0af8Sopenharmony_ci		if (mem_item) {
311419b0af8Sopenharmony_ci			result = -EINVAL;
312419b0af8Sopenharmony_ci			break;
313419b0af8Sopenharmony_ci		}
314419b0af8Sopenharmony_ci
315419b0af8Sopenharmony_ci		mem_item = alloc_dyn_mem_item(configid, cafd, uuid, size);
316419b0af8Sopenharmony_ci		if (!mem_item) {
317419b0af8Sopenharmony_ci			tloge("alloc dyn mem item failed\n");
318419b0af8Sopenharmony_ci			result = -ENOMEM;
319419b0af8Sopenharmony_ci			break;
320419b0af8Sopenharmony_ci		}
321419b0af8Sopenharmony_ci
322419b0af8Sopenharmony_ci		result = proc_alloc_dyn_mem(mem_item);
323419b0af8Sopenharmony_ci		if (result != 0) {
324419b0af8Sopenharmony_ci			tloge("alloc dyn mem failed , ret = %d\n", result);
325419b0af8Sopenharmony_ci			kfree(mem_item);
326419b0af8Sopenharmony_ci			break;
327419b0af8Sopenharmony_ci		}
328419b0af8Sopenharmony_ci		/* register to tee */
329419b0af8Sopenharmony_ci		result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_ADD_DYNAMIC_ION, ret_origin);
330419b0af8Sopenharmony_ci		if (result != 0) {
331419b0af8Sopenharmony_ci			tloge("register to tee failed, result = %d\n", result);
332419b0af8Sopenharmony_ci			proc_free_dyn_mem(mem_item);
333419b0af8Sopenharmony_ci			kfree(mem_item);
334419b0af8Sopenharmony_ci			break;
335419b0af8Sopenharmony_ci		}
336419b0af8Sopenharmony_ci		list_add_tail(&mem_item->head, &g_dynamic_mem_list.list);
337419b0af8Sopenharmony_ci		tloge("log import:alloc ion configid=%d\n",
338419b0af8Sopenharmony_ci			mem_item->configid);
339419b0af8Sopenharmony_ci	} while (0);
340419b0af8Sopenharmony_ci
341419b0af8Sopenharmony_ci	mutex_unlock(&dynamic_mem_lock);
342419b0af8Sopenharmony_ci	return result;
343419b0af8Sopenharmony_ci}
344419b0af8Sopenharmony_ci
345419b0af8Sopenharmony_cistatic void release_configid_mem_locked(uint32_t configid)
346419b0af8Sopenharmony_ci{
347419b0af8Sopenharmony_ci	int result;
348419b0af8Sopenharmony_ci	/* if config id is memid map, and can reuse */
349419b0af8Sopenharmony_ci	do {
350419b0af8Sopenharmony_ci		struct dynamic_mem_item *mem_item =
351419b0af8Sopenharmony_ci		find_memitem_by_configid_locked(configid);
352419b0af8Sopenharmony_ci		if (!mem_item) {
353419b0af8Sopenharmony_ci			tloge("fail to find memitem by configid\n");
354419b0af8Sopenharmony_ci			break;
355419b0af8Sopenharmony_ci		}
356419b0af8Sopenharmony_ci
357419b0af8Sopenharmony_ci		result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_DEL_DYNAMIC_ION, NULL);
358419b0af8Sopenharmony_ci		if (result != 0) {
359419b0af8Sopenharmony_ci			tloge("unregister_from_tee configid=%d, result =%d\n",
360419b0af8Sopenharmony_ci				mem_item->configid, result);
361419b0af8Sopenharmony_ci			break;
362419b0af8Sopenharmony_ci		}
363419b0af8Sopenharmony_ci		proc_free_dyn_mem(mem_item);
364419b0af8Sopenharmony_ci		list_del(&mem_item->head);
365419b0af8Sopenharmony_ci		kfree(mem_item);
366419b0af8Sopenharmony_ci		tloge("log import: free ion\n");
367419b0af8Sopenharmony_ci	} while (0);
368419b0af8Sopenharmony_ci
369419b0af8Sopenharmony_ci	return;
370419b0af8Sopenharmony_ci}
371419b0af8Sopenharmony_ci
372419b0af8Sopenharmony_ci
373419b0af8Sopenharmony_ciint load_app_use_configid(uint32_t configid, uint32_t cafd,
374419b0af8Sopenharmony_ci	const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin)
375419b0af8Sopenharmony_ci{
376419b0af8Sopenharmony_ci	int result;
377419b0af8Sopenharmony_ci
378419b0af8Sopenharmony_ci	if (!uuid)
379419b0af8Sopenharmony_ci		return -EINVAL;
380419b0af8Sopenharmony_ci
381419b0af8Sopenharmony_ci	result = trans_configid2memid(configid, cafd, uuid, size, ret_origin);
382419b0af8Sopenharmony_ci	if (result != 0) {
383419b0af8Sopenharmony_ci		tloge("trans_configid2memid failed ret = %d\n", result);
384419b0af8Sopenharmony_ci		if (release_ion_srv(uuid) != 0)
385419b0af8Sopenharmony_ci			tloge("release ion srv failed\n");
386419b0af8Sopenharmony_ci	}
387419b0af8Sopenharmony_ci	return result;
388419b0af8Sopenharmony_ci}
389419b0af8Sopenharmony_ci
390419b0af8Sopenharmony_ci
391419b0af8Sopenharmony_civoid kill_ion_by_uuid(const struct tc_uuid *uuid)
392419b0af8Sopenharmony_ci{
393419b0af8Sopenharmony_ci	if (!uuid) {
394419b0af8Sopenharmony_ci		tloge("uuid is null\n");
395419b0af8Sopenharmony_ci		return;
396419b0af8Sopenharmony_ci	}
397419b0af8Sopenharmony_ci	mutex_lock(&dynamic_mem_lock);
398419b0af8Sopenharmony_ci	do {
399419b0af8Sopenharmony_ci		struct dynamic_mem_item *mem_item =
400419b0af8Sopenharmony_ci		find_memitem_by_uuid_locked(uuid);
401419b0af8Sopenharmony_ci		if (!mem_item)
402419b0af8Sopenharmony_ci			break;
403419b0af8Sopenharmony_ci		tlogd("kill ION by UUID\n");
404419b0af8Sopenharmony_ci		release_configid_mem_locked(mem_item->configid);
405419b0af8Sopenharmony_ci	} while (0);
406419b0af8Sopenharmony_ci	mutex_unlock(&dynamic_mem_lock);
407419b0af8Sopenharmony_ci}
408419b0af8Sopenharmony_ci
409419b0af8Sopenharmony_civoid kill_ion_by_cafd(unsigned int cafd)
410419b0af8Sopenharmony_ci{
411419b0af8Sopenharmony_ci	struct dynamic_mem_item *item = NULL;
412419b0af8Sopenharmony_ci	struct dynamic_mem_item *temp = NULL;
413419b0af8Sopenharmony_ci	tlogd("kill_ion_by_cafd:\n");
414419b0af8Sopenharmony_ci	mutex_lock(&dynamic_mem_lock);
415419b0af8Sopenharmony_ci	list_for_each_entry_safe(item, temp, &g_dynamic_mem_list.list, head) {
416419b0af8Sopenharmony_ci		if (item->cafd == cafd)
417419b0af8Sopenharmony_ci			release_configid_mem_locked(item->configid);
418419b0af8Sopenharmony_ci	}
419419b0af8Sopenharmony_ci	mutex_unlock(&dynamic_mem_lock);
420419b0af8Sopenharmony_ci}
421419b0af8Sopenharmony_ci
422419b0af8Sopenharmony_ciint load_image_for_ion(const struct load_img_params *params, int32_t *ret_origin)
423419b0af8Sopenharmony_ci{
424419b0af8Sopenharmony_ci	int ret = 0;
425419b0af8Sopenharmony_ci
426419b0af8Sopenharmony_ci	if (!params)
427419b0af8Sopenharmony_ci		return -EFAULT;
428419b0af8Sopenharmony_ci	/* check need to add ionmem */
429419b0af8Sopenharmony_ci	uint32_t configid = params->mb_pack->operation.params[1].value.a;
430419b0af8Sopenharmony_ci	uint32_t ion_size = params->mb_pack->operation.params[1].value.b;
431419b0af8Sopenharmony_ci	int32_t check_result = (configid != 0 && ion_size != 0);
432419b0af8Sopenharmony_ci
433419b0af8Sopenharmony_ci	tloge("check load result=%d, cfgid=%d, ion_size=%d, uuid=%x\n",
434419b0af8Sopenharmony_ci		check_result, configid, ion_size, params->uuid_return->time_low);
435419b0af8Sopenharmony_ci	if (check_result) {
436419b0af8Sopenharmony_ci		ret = load_app_use_configid(configid, params->dev_file->dev_file_id,
437419b0af8Sopenharmony_ci			params->uuid_return, ion_sizeret_origin);
438419b0af8Sopenharmony_ci		if (ret != 0) {
439419b0af8Sopenharmony_ci			tloge("load app use configid failed ret=%d\n", ret);
440419b0af8Sopenharmony_ci			return -EFAULT;
441419b0af8Sopenharmony_ci		}
442419b0af8Sopenharmony_ci	}
443419b0af8Sopenharmony_ci	return ret;
444419b0af8Sopenharmony_ci}
445419b0af8Sopenharmony_ci
446419b0af8Sopenharmony_cibool is_ion_param(uint32_t param_type)
447419b0af8Sopenharmony_ci{
448419b0af8Sopenharmony_ci	if (param_type == TEEC_ION_INPUT ||
449419b0af8Sopenharmony_ci		param_type == TEEC_ION_SGLIST_INPUT)
450419b0af8Sopenharmony_ci		return true;
451419b0af8Sopenharmony_ci	return false;
452419b0af8Sopenharmony_ci}
453419b0af8Sopenharmony_ci
454419b0af8Sopenharmony_cistatic void fill_sg_list(struct sg_table *ion_table,
455419b0af8Sopenharmony_ci	uint32_t ion_list_num, struct sglist *tmp_sglist)
456419b0af8Sopenharmony_ci{
457419b0af8Sopenharmony_ci	uint32_t i;
458419b0af8Sopenharmony_ci	struct page *page = NULL;
459419b0af8Sopenharmony_ci	struct scatterlist *sg = NULL;
460419b0af8Sopenharmony_ci
461419b0af8Sopenharmony_ci	for_each_sg(ion_table->sgl, sg, ion_list_num, i) {
462419b0af8Sopenharmony_ci		page = sg_page(sg);
463419b0af8Sopenharmony_ci		tmp_sglist->page_info[i].phys_addr = page_to_phys(page);
464419b0af8Sopenharmony_ci		tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE;
465419b0af8Sopenharmony_ci	}
466419b0af8Sopenharmony_ci}
467419b0af8Sopenharmony_ci
468419b0af8Sopenharmony_cistatic int check_sg_list(const struct sg_table *ion_table, uint32_t ion_list_num)
469419b0af8Sopenharmony_ci{
470419b0af8Sopenharmony_ci	struct scatterlist *sg = NULL;
471419b0af8Sopenharmony_ci	uint32_t i;
472419b0af8Sopenharmony_ci	for_each_sg(ion_table->sgl, sg, ion_list_num, i) {
473419b0af8Sopenharmony_ci		if (!sg) {
474419b0af8Sopenharmony_ci			tloge("an error sg when get ion sglist \n");
475419b0af8Sopenharmony_ci			return -EFAULT;
476419b0af8Sopenharmony_ci		}
477419b0af8Sopenharmony_ci	}
478419b0af8Sopenharmony_ci	return 0;
479419b0af8Sopenharmony_ci}
480419b0af8Sopenharmony_ci
481419b0af8Sopenharmony_cistatic int get_ion_sg_list_from_fd(uint32_t ion_shared_fd,
482419b0af8Sopenharmony_ci	uint32_t ion_alloc_size, phys_addr_t *sglist_table,
483419b0af8Sopenharmony_ci	size_t *ion_sglist_size)
484419b0af8Sopenharmony_ci{
485419b0af8Sopenharmony_ci	struct sg_table *ion_table = NULL;
486419b0af8Sopenharmony_ci	struct sglist *tmp_sglist = NULL;
487419b0af8Sopenharmony_ci	uint64_t ion_id = 0;
488419b0af8Sopenharmony_ci	enum SEC_SVC ion_type = 0;
489419b0af8Sopenharmony_ci	uint32_t ion_list_num = 0;
490419b0af8Sopenharmony_ci	uint32_t sglist_size;
491419b0af8Sopenharmony_ci#ifdef CONFIG_DMABUF_MM
492419b0af8Sopenharmony_ci	if (mm_dma_heap_secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) {
493419b0af8Sopenharmony_ci#else
494419b0af8Sopenharmony_ci	if (secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) {
495419b0af8Sopenharmony_ci#endif
496419b0af8Sopenharmony_ci		tloge("get ion table failed. \n");
497419b0af8Sopenharmony_ci		return -EFAULT;
498419b0af8Sopenharmony_ci	}
499419b0af8Sopenharmony_ci
500419b0af8Sopenharmony_ci	if (ion_type != SEC_DRM_TEE) {
501419b0af8Sopenharmony_ci		if (ion_table->nents <= 0 || ion_table->nents > MAX_ION_NENTS)
502419b0af8Sopenharmony_ci			return -EFAULT;
503419b0af8Sopenharmony_ci		ion_list_num = (uint32_t)(ion_table->nents & INT_MAX);
504419b0af8Sopenharmony_ci		if (check_sg_list(ion_table, ion_list_num) != 0)
505419b0af8Sopenharmony_ci			return -EFAULT;
506419b0af8Sopenharmony_ci	}
507419b0af8Sopenharmony_ci	/* ion_list_num is less than 1024, so sglist_size won't flow */
508419b0af8Sopenharmony_ci	sglist_size = sizeof(struct ion_page_info) * ion_list_num + sizeof(*tmp_sglist);
509419b0af8Sopenharmony_ci	tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO);
510419b0af8Sopenharmony_ci	if (!tmp_sglist) {
511419b0af8Sopenharmony_ci		tloge("sglist mem alloc failed\n");
512419b0af8Sopenharmony_ci		return -ENOMEM;
513419b0af8Sopenharmony_ci	}
514419b0af8Sopenharmony_ci	tmp_sglist->sglist_size = (uint64_t)sglist_size;
515419b0af8Sopenharmony_ci	tmp_sglist->ion_size = (uint64_t)ion_alloc_size;
516419b0af8Sopenharmony_ci	tmp_sglist->info_length = (uint64_t)ion_list_num;
517419b0af8Sopenharmony_ci	if (ion_type != SEC_DRM_TEE)
518419b0af8Sopenharmony_ci		fill_sg_list(ion_table, ion_list_num, tmp_sglist);
519419b0af8Sopenharmony_ci	else
520419b0af8Sopenharmony_ci		tmp_sglist->ion_id = ion_id;
521419b0af8Sopenharmony_ci
522419b0af8Sopenharmony_ci	*sglist_table = mailbox_virt_to_phys((uintptr_t)tmp_sglist);
523419b0af8Sopenharmony_ci	*ion_sglist_size = sglist_size;
524419b0af8Sopenharmony_ci	return 0;
525419b0af8Sopenharmony_ci}
526419b0af8Sopenharmony_ci
527419b0af8Sopenharmony_ciint alloc_for_ion_sglist(const struct tc_call_params *call_params,
528419b0af8Sopenharmony_ci	struct tc_op_params *op_params, uint8_t kernel_params,
529419b0af8Sopenharmony_ci	uint32_t param_type, unsigned int index)
530419b0af8Sopenharmony_ci{
531419b0af8Sopenharmony_ci	struct tc_ns_operation *operation = NULL;
532419b0af8Sopenharmony_ci	size_t ion_sglist_size = 0;
533419b0af8Sopenharmony_ci	phys_addr_t ion_sglist_addr = 0x0;
534419b0af8Sopenharmony_ci	union tc_ns_client_param *client_param = NULL;
535419b0af8Sopenharmony_ci	unsigned int ion_shared_fd = 0;
536419b0af8Sopenharmony_ci	unsigned int ion_alloc_size;
537419b0af8Sopenharmony_ci	uint64_t a_addr, b_addr;
538419b0af8Sopenharmony_ci
539419b0af8Sopenharmony_ci	/* this never happens */
540419b0af8Sopenharmony_ci	if (index >= TEE_PARAM_NUM || !call_params || !op_params)
541419b0af8Sopenharmony_ci		return -EINVAL;
542419b0af8Sopenharmony_ci
543419b0af8Sopenharmony_ci	operation = &op_params->mb_pack->operation;
544419b0af8Sopenharmony_ci	client_param = &(call_params->context->params[index]);
545419b0af8Sopenharmony_ci	a_addr = client_param->value.a_addr |
546419b0af8Sopenharmony_ci	((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM);
547419b0af8Sopenharmony_ci	b_addr = client_param->value.b_addr |
548419b0af8Sopenharmony_ci	((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM);
549419b0af8Sopenharmony_ci
550419b0af8Sopenharmony_ci	if (read_from_client(&operation->params[index].value.a,
551419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.a),
552419b0af8Sopenharmony_ci		(void *)(uintptr_t)a_addr,
553419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.a), kernel_params)) {
554419b0af8Sopenharmony_ci		tloge("valuea copy failed\n");
555419b0af8Sopenharmony_ci		return -EFAULT;
556419b0af8Sopenharmony_ci	}
557419b0af8Sopenharmony_ci	if (read_from_client(&operation->params[index].value.b,
558419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.b),
559419b0af8Sopenharmony_ci		(void *)(uintptr_t)b_addr,
560419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.b), kernel_params)) {
561419b0af8Sopenharmony_ci		tloge("valueb copy failed\n");
562419b0af8Sopenharmony_ci		return -EFAULT;
563419b0af8Sopenharmony_ci	}
564419b0af8Sopenharmony_ci	ion_shared_fd = operation->params[index].value.a;
565419b0af8Sopenharmony_ci	ion_alloc_size = operation->params[index].value.b;
566419b0af8Sopenharmony_ci
567419b0af8Sopenharmony_ci	if(get_ion_sg_list_from_fd(ion_shared_fd, ion_alloc_size,
568419b0af8Sopenharmony_ci		&ion_sglist_addr, &ion_sglist_size)) {
569419b0af8Sopenharmony_ci		tloge("get ion sglist failed, fd=%u\n", ion_shared_fd);
570419b0af8Sopenharmony_ci		return -EFAULT;
571419b0af8Sopenharmony_ci	}
572419b0af8Sopenharmony_ci	op_params->local_tmpbuf[index].temp_buffer = phys_to_virt(ion_sglist_addr);
573419b0af8Sopenharmony_ci	op_params->local_tmpbuf[index].size = ion_sglist_size;
574419b0af8Sopenharmony_ci
575419b0af8Sopenharmony_ci	operation->params[index].memref.buffer = (unsigned int)ion_sglist_addr;
576419b0af8Sopenharmony_ci	operation->buffer_h_addr[index] =
577419b0af8Sopenharmony_ci	(uint64_t)ion_sglist_addr >> ADDR_TRANS_NUM;
578419b0af8Sopenharmony_ci	operation->params[index].memref.size = (unsigned int)ion_sglist_size;
579419b0af8Sopenharmony_ci	op_params->trans_paramtype[index] = param_type;
580419b0af8Sopenharmony_ci
581419b0af8Sopenharmony_ci	return 0;
582419b0af8Sopenharmony_ci}
583419b0af8Sopenharmony_ci
584419b0af8Sopenharmony_cistatic int transfer_ion_params(struct tc_ns_operation *operation,
585419b0af8Sopenharmony_ci	union tc_ns_client_param *client_param, uint8_t kernel_params,
586419b0af8Sopenharmony_ci	unsigned int index)
587419b0af8Sopenharmony_ci{
588419b0af8Sopenharmony_ci	uint64_t a_addr = client_param->value.a_addr |
589419b0af8Sopenharmony_ci	((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM);
590419b0af8Sopenharmony_ci	uint64_t b_addr = client_param->value.b_addr |
591419b0af8Sopenharmony_ci	((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM);
592419b0af8Sopenharmony_ci
593419b0af8Sopenharmony_ci	if (read_from_client(&operation->params[index].value.a,
594419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.a),
595419b0af8Sopenharmony_ci		(void *)(uintptr_t)a_addr,
596419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.a), kernel_params)) {
597419b0af8Sopenharmony_ci		tloge("value.a_addr copy failed\n");
598419b0af8Sopenharmony_ci		return -EFAULT;
599419b0af8Sopenharmony_ci	}
600419b0af8Sopenharmony_ci
601419b0af8Sopenharmony_ci	if (read_from_client(&operation->params[index].value.b,
602419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.b),
603419b0af8Sopenharmony_ci		(void *)(uintptr_t)b_addr,
604419b0af8Sopenharmony_ci		sizeof(operation->params[index].value.b), kernel_params)) {
605419b0af8Sopenharmony_ci		tloge("value.b_addr copy failed\n");
606419b0af8Sopenharmony_ci		return -EFAULT;
607419b0af8Sopenharmony_ci	}
608419b0af8Sopenharmony_ci
609419b0af8Sopenharmony_ci	return 0;
610419b0af8Sopenharmony_ci}
611419b0af8Sopenharmony_ci
612419b0af8Sopenharmony_ciint alloc_for_ion(const struct tc_call_params *call_params,
613419b0af8Sopenharmony_ci	struct tc_op_params *op_params, uint8_t kernel_params,
614419b0af8Sopenharmony_ci	uint32_t param_type, unsigned int index)
615419b0af8Sopenharmony_ci{
616419b0af8Sopenharmony_ci	struct tc_ns_operation *operation = NULL;
617419b0af8Sopenharmony_ci	size_t drm_ion_size = 0;
618419b0af8Sopenharmony_ci	phys_addr_t drm_ion_phys = 0x0;
619419b0af8Sopenharmony_ci	struct dma_buf *drm_dma_buf = NULL;
620419b0af8Sopenharmony_ci	union tc_ns_client_param *client_param = NULL;
621419b0af8Sopenharmony_ci	unsigned int ion_shared_fd = 0;
622419b0af8Sopenharmony_ci	int ret = 0;
623419b0af8Sopenharmony_ci
624419b0af8Sopenharmony_ci	/* this never happens */
625419b0af8Sopenharmony_ci	if (index >= TEE_PARAM_NUM || !call_params || !op_params)
626419b0af8Sopenharmony_ci		return -EINVAL;
627419b0af8Sopenharmony_ci
628419b0af8Sopenharmony_ci	operation = &op_params->mb_pack->operation;
629419b0af8Sopenharmony_ci	client_param = &(call_params->context->params[index]);
630419b0af8Sopenharmony_ci	if (transfer_ion_params(operation, client_param, kernel_params, index))
631419b0af8Sopenharmony_ci		return -EFAULT;
632419b0af8Sopenharmony_ci
633419b0af8Sopenharmony_ci	ion_shared_fd = operation->params[index].value.a;
634419b0af8Sopenharmony_ci	drm_dma_buf = dma_buf_get(ion_shared_fd);
635419b0af8Sopenharmony_ci	if (IS_ERR_OR_NULL(drm_dma_buf)) {
636419b0af8Sopenharmony_ci		tloge("drm dma buf is err, ret = %d fd = %u\n", ret, ion_shared_fd);
637419b0af8Sopenharmony_ci		return -EFAULT;
638419b0af8Sopenharmony_ci	}
639419b0af8Sopenharmony_ci#ifdef CONFIG_DMABUF_MM
640419b0af8Sopenharmony_ci	ret = mm_dma_heap_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size);
641419b0af8Sopenharmony_ci#else
642419b0af8Sopenharmony_ci	ret = ion_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size);
643419b0af8Sopenharmony_ci#endif
644419b0af8Sopenharmony_ci	if (ret != 0) {
645419b0af8Sopenharmony_ci		tloge("in %s err:ret=%d fd=%u\n", __func__, ret, ion_shared_fd);
646419b0af8Sopenharmony_ci		dma_buf_put(drm_dma_buf);
647419b0af8Sopenharmony_ci		return -EFAULT;
648419b0af8Sopenharmony_ci	}
649419b0af8Sopenharmony_ci
650419b0af8Sopenharmony_ci	if (drm_ion_size > operation->params[index].value.b)
651419b0af8Sopenharmony_ci		drm_ion_size = operation->params[index].value.b;
652419b0af8Sopenharmony_ci	operation->params[index].value.a = (unsigned int)drm_ion_phys;
653419b0af8Sopenharmony_ci	operation->params[index].value.b = (unsigned int)drm_ion_size;
654419b0af8Sopenharmony_ci	op_params->trans_paramtype[index] = param_type;
655419b0af8Sopenharmony_ci	dma_buf_put(drm_dma_buf);
656419b0af8Sopenharmony_ci
657419b0af8Sopenharmony_ci	return ret;
658419b0af8Sopenharmony_ci}