diff --git a/123/.keep b/123/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/chcore/chcore_interface/TA/interface_test.h b/chcore/chcore_interface/TA/interface_test.h new file mode 100644 index 0000000000000000000000000000000000000000..d9ad6ebe84e05cf736b51766694f625aa3dda97d --- /dev/null +++ b/chcore/chcore_interface/TA/interface_test.h @@ -0,0 +1,25 @@ +#ifndef _INTERFACE_TEST_H__ +#define _INTERFACE_TEST_H__ + +#include +#include +#include +#include +#include +#include +#include +#include "tee_crypto_api.h" +#include "tee_log.h" + +#define TEEC_INTERFACE_CA "/vendor/bin/test_chcore_interface" +#define TEEC_INTERFACE_CA_UID 0 +#define LIBCORE_SHARE_NAME "libc_share.so" +typedef uint64_t cref_t + +enum +{ + CHCORE_CMD_ID_IPC_TEST, +}; + +void *get_libcore_shared_handle(void); +#endif \ No newline at end of file diff --git a/chcore/chcore_interface/TA/ipc_interface_test.c b/chcore/chcore_interface/TA/ipc_interface_test.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/chcore/chcore_interface/TA/ipc_interface_test.h b/chcore/chcore_interface/TA/ipc_interface_test.h new file mode 100644 index 0000000000000000000000000000000000000000..95e5ee462eb32a3a80d8797ab929214c2fb6d2c6 --- /dev/null +++ b/chcore/chcore_interface/TA/ipc_interface_test.h @@ -0,0 +1,22 @@ +#ifndef _IPC_INTERFACE_TEST_H__ +#define _IPC_INTERFACE_TEST_H__ + +#include "interface_test.h" + +#define BUFFER_MAX_LEN 100 + +enum message msgtype +{ + MSG_TYPE_INVALID = 0, + MSG_TYPE_NOTIF = 1, + MSG_TYPE_CALL = 2 +}; + +struct reg_iyems_st +{ + bool reg_pid; + bool reg_name; + +} + +#end \ No newline at end of file diff --git a/tzdriver/ion/Kconfig b/tzdriver/ion/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..dae0cecc5e400149e2fb8f7eaf8f29e6e870bc4c --- /dev/null +++ b/tzdriver/ion/Kconfig @@ -0,0 +1,13 @@ +config DYNAMIC_ION + bool "Dynamic Ion Feature" + default n + depends on TZDRIVER + help + TEEOS dynamic ion + +config STATIC_ION + bool "Static Ion Feature" + default n + depends on TZDRIVER + help + TEEOS static ion \ No newline at end of file diff --git a/tzdriver/ion/Makefile b/tzdriver/ion/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cf4b92e8d167edbc29d7cd193fedd06196830cde --- /dev/null +++ b/tzdriver/ion/Makefile @@ -0,0 +1,20 @@ +KERNEL_DIR :=$(srctree) + +ifneq ($(TARGET_BUILD_VARIANT),user) + ccflags-y += -DDEF_ENG +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/core +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/staging/android + +obj-$(CONFIG_STATIC_ION) += static_ion_mem.o +obj-$(CONFIG_DYNAMIC_ION) += dynamic_ion_mem.o +ifneq ($(CONFIG_MTK_PLATFORM), ) + obj-$(CONFIG_STATIC_ION) += mplat/declare_static_ion.o +else + obj-$(CONFIG_STATIC_ION) += generic/declare_static_ion.o +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/include +EXTRA_CFLAGS += -include internal_functions.h \ No newline at end of file diff --git a/tzdriver/ion/declare_static_ion.h b/tzdriver/ion/declare_static_ion.h new file mode 100644 index 0000000000000000000000000000000000000000..1632479d6589f5500e561f3d5b5311c4540929f0 --- /dev/null +++ b/tzdriver/ion/declare_static_ion.h @@ -0,0 +1,7 @@ +#ifndef DECLARE_STATIC_ION_H +#define DECLARE_STATIC_ION_H +#include "static_ion_mem.h" + +void set_ion_mem_info(struct register_ion_mem_tag *memtag); + +#endif \ No newline at end of file diff --git a/tzdriver/ion/dynamic_ion_mem.c b/tzdriver/ion/dynamic_ion_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..f2e23f8cb1d718cba54acbaad97491ec3f2039f5 --- /dev/null +++ b/tzdriver/ion/dynamic_ion_mem.c @@ -0,0 +1,637 @@ +#include "dynamic_ion_mem.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CONFIG_DMABUF_MM +#include +#endif +#include +#include +#include +#include +#if ((#defined CONFIG_ION_MM) || (#defined CONFIG_ION_MM_SECSG)) +#include +#endif +#ifdef CONFIG_DMABUF_MM +#include +#endif +#include "tc_ns_log.h" +#include "tc_ns_client.h" +#include "smc_smp.h" +#include "gp_ops.h" +#include "teek_client_constants.h" +#include "mailbox_mempool.h" +#include "dynamic_ion_uuid.h" + +static DEFINE_MUTEX(dynamic_mem_lock); +struct dynamic_mem_list { + struct list_head list; +}; + +static const struct dynamic_mem_config g_dyn_mem_config[] = { + #ifdef DEF_ENG + {TEE_SERVICE_UT, SEC_EID}, + {TEE_SERVICE_TEST_DYNION, SEC_AI_ION}, + #endif + {TEE_SECIDENTIFICATION1, SEC_EID}, + {TEE_SECIDENTIFICATION3, SEC_EID}, + {TEE_SERVICE_AI, SEC_AI_ION}, + {TEE_SERVICE_AI_TINY, SEC_AI_ION}, + {TEE_SERVICE_VCODEC, SEC_DRM_TEE}, +}; + +static struct dynamic_mem_list g_dynamic_mem_list; +static const uint32_t g_dyn_mem_config_mem = ARRAY_SIZE(g_dynamic_mem_list); + +static int release_ion_srv(const struct tc_uuid *uuid) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + + smc_cmd.err_origin = TEEC_ORIGIN_COMMS; + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = GLOBAL_CMD_ID_RELEASE_ION_SRV; + if (memcpy_s(&smc_cmd.uuid, sizeof(smc_cmd.uuid), uuid, sizeof(*uuid))) { + tloge("copy uuid failed\n"); + return -ENOMEM; + } + + if (tc_ns_smc(&smc_cmd)) { + tloge("send release ion srv cmd failed\n"); + return -EPERM; + } + return 0; +} + + +static int get_ion_sglist(struct dynamic_mem_item *mem_item) +{ + struct sglist *tmp_sglist = NULL; + struct scatterlist *sg = NULL; + struct page *page = NULL; + uint32_t sglist_size; + uint32_t i = 0; + struct sg_table *ion_sg_table = mem_item->memory.dyn_sg_table; + + if (!ion_sg_table) + return -EINVAL; + + if (ion_sg_table->nents <= 0 || ion_sg_table->nents > MAX_ION_NENTS) + return -EINVAL; + + for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) { + if (!sg) { + tloge("an error sg when get ion sglist\n"); + return -EINVAL; + } + } + + sglist_size = sizeof(struct ion_page_info) * ion_sg_table->nents + sizeof(*tmp_sglist); + tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO); + if (!tmp_sglist) { + tloge("mailbox alloc failed\n"); + return -ENOMEM; + } + + tmp_sglist->sglist_size = (uint64_t)sglist_size; + tmp_sglist->ion_size = (uint64_t)mem_item->size; + tmp_sglist->info_length = (uint64_t)ion_sg_table->nents; + for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) { + page = sg_page(sg); + tmp_sglist->page_info[i].phys_addr = page_to_phys(page); + tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE; + } + mem_item->memory.ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_sglist); + mem_item->memory.len = sglist_size; + return 0; +} + +static int send_dyn_ion_cmd(struct dynamic_mem_item *mem_item, unsigned int cmd_id, int32_t *ret_origin) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + int ret; + struct mb_cmd_pack *mb_pack = NULL; + + if (!mem_item) { + tloge("mem_item is null\n"); + return -EINVAL; + } + + ret = get_ion_sglist(mem_item); + if (ret != 0) + return ret; + + mb_pack = mailbox_alloc_cmd_pack(); + if (!mb_pack) { + mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr)); + tloge("alloc cmd pack failed\n"); + return -ENOMEM; + } + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = cmd_id; + smc_cmd.err_origin = TEEC_ORIGIN_COMMS; + mb_pack->operation.paramtypes = teec_param_types( + TEE_PARAM_TYPE_ION_SGLIST_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_NONE); + + mb_pack->operation.params[0].memref.size = (uint32_t)mem_item->memory.len; + mb_pack->operation.params[0].memory.buffer = + (uint32_t)(mem_item->memory.ion_phys_addr & 0xFFFFFFFF); + mb_pack->operation.buffer_h_addr[0] = + (uint64_t)(mem_item->memory.ion_phys_addr) >> ADDR_TRANS_NUM; + mb_pack->operation.params[1].value.a = (uint32_t)mem_item->size; + mb_pack->operation.params[2].value.a = mem_item->configid; + smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; + + if (tc_ns_smc(&smc_cmd)) { + if (ret_origin) + *ret_origin = smc_cmd.err_origin; + ret = -EPERM; + tlogd("send loadapp ion failed\n"); + } + mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr)); + mailbox_free(mb_pack); + return ret; +} + +static struct dynamic_mem_item *find_memitem_by_configid_locked(uint32_t configid) +{ + struct dynamic_mem_item *item = NULL; + list_for_each_entry(item, &g_dynamic_mem_list.list, head) { + if (item->configid == configid) + return item; + } + return NULL; +} + +static struct dynamic_mem_item *find_memitem_by_uuid_locked(const struct tc_uuid *uuid) +{ + struct dynamic_mem_item *item = NULL; + list_for_each_entry(item, &g_dynamic_mem_list.list, head) { + if (!memcmp(&item->uuid, uuid, sizeof(*uuid))) + return item; + } + return NULL; +} + +#define BLOCK_64KB_SIZE (64 * 1024) /* 64 */ +#define BLOCK_64KB_MASK 0xFFFFFFFFFFFF0000 +/* size should be aligned with 64KB */ +#define BLOCK_64KB_SIZE_MASK (BLOCK_64KB_SIZE -1) +static int proc_alloc_dyn_mem(struct dynamic_mem_item *mem_item) +{ + struct sg_table *ion_sg_table = NULL; + + if (mem_item->size + BLOCK_64KB_SIZE_MASK < mem_item->size) { + tloge("ion size is error, size = %x\n", mem_item->size); + return _EINVAL; + } + mem_item->memory.len = (mem_item ->size + BLOCK_64KB_SIZE_MASK) & BLOCK_64KB_MASK; + + ion_sg_table = mm_secmem_alloc(mem_item->addr_sec_region, + mem_item->memory.len); + if (!ion_sg_table) { + tloge("failed to get ion page, configid = %d\n", + mem_item->configid); + return _ENOMEM; + } + mem_item->memory.dyn_sg_table = ion_sg_table; + return 0; +} + +static void proc_free_dyn_mem(struct dynamic_mem_item *mem_item) +{ + if (!mem_item->memory.dyn_sg_table) { + tloge("ion_phys_addr is NULL\n"); + return; + } + mm_secmem_free(mem_item->addr_sec_region, + mem_item->memory.dyn_sg_table); + mem_item->memory.dyn_sg_table = NULL; + return; +} + +int init_dynamic_mem(void) +{ + INIT_LIST_HEAD(&(g_dynamic_mem_list.list)); + return 0; +} + +static int32_t find_ddr_sec_region_by_uuid(const struct tc_uuid *uuid, + uint32_t *ddr_sec_region) +{ + uint32_t i; + for (i = 0; i < g_dyn_mem_config_num; i++) { + if (!memcmp(&(g_dyn_mem_config[i].uuid), uuid, + sizeof(*uuid))) { + *ddr_sec_region = g_dyn_mem_config[i].ddr_sec_region; + return 0; + } + } + return -EINVAL; +} + +static struct dynamic_mem_item *alloc_dyn_mem_item(uint32_t configid, + uint32_t cafd, const struct tc_uuid *uuid, uint32_t size) +{ + uint32_t ddr_sec_region; + struct dynamic_mem_item *mem_item = NULL; + int32_t result; + + result = find_ddr_sec_region_by_uuid(uuid, &ddr_sec_region); + if (result != 0) { + tloge("find ddr sec region failed\n"); + return NULL; + } + + mem_item = kzalloc(sizeof(*mem_item), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)mem_item)) { + tloge("alloc mem item failed\n"); + return NULL; + } + + mem_item->ddr_sec_region = ddr_sec_region; + mem_item->configid = configid; + mem_item->size = size; + mem_item->cafd = cafd; + result = memcpy_s(&mem_item->uuid, sizeof(mem_item->uuid), uuid, + sizeof(*uuid)); + if(result != EOK) { + tloge("memcpy uuid failed\n"); + kfree(mem_item); + return NULL; + } + return mem_item; +} + + +static int trans_configid2memid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + int result; + + if (!uuid) + return -EINVAL; + mutex_lock(&dynamic_mem_lock); + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_configid_locked(configid); + if (mem_item) { + result = -EINVAL; + break; + } + + mem_item = alloc_dyn_mem_item(configid, cafd, uuid, size); + if (!mem_item) { + tloge("alloc dyn mem item failed\n"); + result = -ENOMEM; + break; + } + + result = proc_alloc_dyn_mem(mem_item); + if (result != 0) { + tloge("alloc dyn mem failed , ret = %d\n", result); + kfree(mem_item); + break; + } + /* register to tee */ + result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_ADD_DYNAMIC_ION, ret_origin); + if (result != 0) { + tloge("register to tee failed, result = %d\n", result); + proc_free_dyn_mem(mem_item); + kfree(mem_item); + break; + } + list_add_tail(&mem_item->head, &g_dynamic_mem_list.list); + tloge("log import:alloc ion configid=%d\n", + mem_item->configid); + } while (0); + + mutex_unlock(&dynamic_mem_lock); + return result; +} + +static void release_configid_mem_locked(uint32_t configid) +{ + int result; + /* if config id is memid map, and can reuse */ + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_configid_locked(configid); + if (!mem_item) { + tloge("fail to find memitem by configid\n"); + break; + } + + result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_ADD_DYNAMIC_ION, NULL); + if (result != 0) { + tloge("unregister_from_tee configid=%d, result =%d\n", + mem_item->configid, result); + break; + } + proc_free_dyn_mem(mem_item); + list_del(&mem_item->head); + kfree(mem_item); + tloge("log import: free ion\n"); + } while (0); + + return; +} + + +int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + int result; + + if (!uuid) + return -EINVAL; + + result = trans_configid2memid(configid, cafd, uuid, size, ret_origin); + if (result != 0) { + tloge("trans_configid2memid failed ret = %d\n", result); + if (release_ion_srv(uuid) != 0) + tloge("release ion srv failed\n"); + } + return result; +} + + +void kill_ion_by_uuid(const struct tc_uuid *uuid) +{ + if (!uuid) { + tloge("uuid is null\n"); + return; + } + mutex_lock(&dynamic_mem_lock); + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_uuid_locked(uuid); + if (!mem_item) + break; + tlogd("kill ION by UUID\n"); + release_configid_mem_locked(mem_item->configid); + } while (0); + mutex_unlock(&dynamic_mem_lock); +} + +void kill_ion_by_cafd(unsigned int cafd) +{ + struct dynamic_mem_item *item = NULL; + struct dynamic_mem_item *temp = NULL; + tlogd("kill_ion_by_cafd:\n"); + mutex_lock(&dynamic_mem_lock); + list_for_each_entry_safe(item, temp, &g_dynamic_mem_list.list, head) { + if (item->cafd == cafd) + release_configid_mem_locked(item->configid); + } + mutex_unlock(&dynamic_mem_lock); +} + +int load_image_for_ion(const struct load_img_params *params, int32_t *ret_origin) +{ + int ret = 0; + + if (!params) + return -EFAULT; + /* check need to add ionmem */ + uint32_t configid = params->mb_pack->operation.params[1].value.a; + uint32_t ion_size = params->mb_pack->operation.params[1].value.b; + int32_t check_result = (configid != 0 && ion_size != 0); + + tloge("check load result=%d, cfgid=%d, ion_size=%d, uuid=%x\n", + check_result, configid, ion_size, params->uuid_return->time_low); + if (check_result) { + ret = load_app_use_configid(configid, params->dev_file->dev_file_id, + params->uuid_return, ion_size, ret_origin); + if (ret != 0) { + tloge("load app use configid failed ret=%d\n", ret); + return -EFAULT; + } + } + return ret; +} + +bool is_ion_param(uint32_t param_type) +{ + if (param_type == TEEC_ION_INPUT || + param_type == TEEC_ION_SGLIST_INPUT) + return true; + return false; +} + +static void fill_sg_list(struct sg_table *ion_table, + uint32_t ion_list_num, struct sglist *tmp_sglist) +{ + uint32_t i; + struct page *page = NULL; + struct scatterlist *sg = NULL; + + for_each_sg(ion_table->sgl, sg, ion_list_num, i) { + page = sg_page(sg); + tmp_sglist->page_info[i].phys_addr = page_to_phys(page); + tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE; + } +} + +static int check_sg_list(const struct sg_table *ion_table, uint32_t ion_list_num) +{ + struct scatterlist *sg = NULL; + uint32_t i; + for_each_sg(ion_table->sgl, sg, ion_list_num, i) { + if (!sg) { + tloge("an error sg when get ion sglist \n"); + return -EFAULT; + } + } + return 0; +} + +static int get_ion_sg_list_from_fd(uint32_t ion_shared_fd, + uint32_t ion_alloc_size, phys_addr_t *sglist_table, + size_t *ion_sglist_size) +{ + struct sg_table *ion_table = NULL; + struct sglist *tmp_sglist = NULL; + uint64_t ion_id = 0; + enum SEC_SVC ion_type = 0; + uint32_t ion_list_num = 0; + uint32_t sglist_size; +#ifdef CONFIG_DMABUF_MM + if (mm_dma_heap_secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) { +#else + if (secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) { +#endif + tloge("get ion table failed. \n"); + return -EFAULT; + } + + if (ion_type != SEC_DRM_TEE) { + if (ion_table->nents <= 0 || ion_table->nents > MAX_ION_NENTS) + return -EFAULT; + ion_list_num = (uint32_t)(ion_table->nents & INT_MAX); + if (check_sg_list(ion_table, ion_list_num) != 0) + return -EFAULT; + } + /* ion_list_num is less than 1024, so sglist_size won't flow */ + sglist_size = sizeof(struct ion_page_info) * ion_list_num + sizeof(*tmp_sglist); + tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO); + if (!tmp_sglist) { + tloge("sglist mem alloc failed\n"); + return -ENOMEM; + } + tmp_sglist->sglist_size = (uint64_t)sglist_size; + tmp_sglist->ion_size = (uint64_t)ion_alloc_size; + tmp_sglist->info_length = (uint64_t)ion_list_num; + if (ion_type != SEC_DRM_TEE) + fill_sg_list(ion_table, ion_list_num, tmp_sglist); + else + tmp_sglist->ion_id = ion_id; + + *sglist_table = mailbox_virt_to_phys((uintptr_t)tmp_sglist); + *ion_sglist_size = sglist_size; + return 0; +} + +int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + struct tc_ns_operation *operation = &op_params->mb_pack->operation; + size_t ion_sglist_size = 0; + phys_addr_t ion_sglist_addr = 0x0; + union tc_ns_client_param *client_param = NULL; + unsigned int ion_shared_fd = 0; + unsigned int ion_alloc_size; + uint64_t a_addr, b_addr; + + /* this never happens */ + if (index >= TEE_PARAM_NUM || !call_params || !op_params) + return -EINVAL; + + client_param = &(call_params->context->params[index]); + a_addr = client_param->value.a_addr | + ((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM); + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + + if (read_from_client(&operation->params[index].value.a, + sizeof(operation->params[index].value.a), + (void *)(uintptr_t)a_addr, + sizeof(operation->params[index].value.a), kernel_params)) { + tloge("valuea copy failed\n"); + return -EFAULT; + } + if (read_from_client(&operation->params[index].value.b, + sizeof(operation->params[index].value.b), + (void *)(uintptr_t)a_addr, + sizeof(operation->params[index].value.b), kernel_params)) { + tloge("valueb copy failed\n"); + return -EFAULT; + } + ion_shared_fd = operation->params[index].value.a; + ion_alloc_size = operation->params[index].value.b; + + if(get_ion_sg_list_from_fd(ion_shared_fd, ion_alloc_size, + &ion_sglist_addr, &ion_sglist_size)) { + tloge("get ion sglist failed, fd=%u\n", ion_shared_fd); + return -EFAULT; + } + op_params->local_tmpbuf[index].temp_buffer = phys_to_virt(ion_sglist_addr); + op_params->local_tmpbuf[index].size = ion_sglist_size; + + operation->params[index].memref.buffer = (unsigned int)ion_sglist_addr; + operation->buffer_h_addr[index] = + (uint64_t)ion_sglist_addr >> ADDR_TRANS_NUM; + operation->params[index].memref.size = (unsigned int)ion_sglist_size; + op_params->trans_paramtype[index] = param_type; + + return 0; +} + +static int transfer_ion_params(struct tc_ns_operation *operation, + union tc_ns_client_param *client_param, uint8_t kernel_params, + unsigned int index) +{ + uint64_t a_addr = client_param->value.a_addr | + ((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM); + uint64_t b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + + if (read_from_client(&operation->params[index].value.a, + sizeof(operation->params[index].value.a), + (void *)(uintptr_t)a_addr, + sizeof(operation->params[index].value.a), kernel_params)) { + tloge("value.a_addr copy failed\n"); + return -EFAULT; + } + + if (read_from_client(&operation->params[index].value.b, + sizeof(operation->params[index].value.b), + (void *)(uintptr_t)b_addr, + sizeof(operation->params[index].value.b), kernel_params)) { + tloge("value.b_addr copy failed\n"); + return -EFAULT; + } + + return 0; +} + +int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + struct tc_ns_operation *operation = &op_params->mb_pack->operation; + size_t drm_ion_size = 0; + phys_addr_t drm_ion_phys = 0x0; + struct dma_buf *drm_dma_buf = NULL; + union tc_ns_client_param *client_param = NULL; + unsigned int ion_shared_fd = 0; + int ret = 0; + + /* this never happens */ + if (index >= TEE_PARAM_NUM || !call_params || !op_params) + return -EINVAL; + + client_param = &(call_params->context->params[index]); + if (transfer_ion_params(operation, client_param, kernel_params, index)) + return -EFAULT; + + ion_shared_fd = operation->params[index].value.a; + drm_dma_buf = dma_buf_get(ion_shared_fd); + if (IS_ERR_OR_NULL(drm_dma_buf)) { + tloge("drm dma buf is err, ret = %d fd = %u\n", ret, ion_shared_fd); + return -EFAULT; + } +#ifdef CONFIG_DMABUF_MM + ret = mm_dma_heap_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size); +#else + ret = ion_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size); +#endif + if (ret != 0) { + tloge("in %s err:ret=%d fd=%u\n", __func__, ret, ion_shared_fd); + dma_buf_put(drm_dma_buf); + return -EFAULT; + } + + if (drm_ion_size > operation->params[index].value.b) + drm_ion_size = operation->params[index].value.b; + operation->params[index].value.a = (unsigned int)drm_ion_phys; + operation->params[index].value.b = (unsigned int)drm_ion_size; + op_params->trans_paramtype[index] = param_type; + dma_buf_put(drm_dma_buf); + + return ret; +} \ No newline at end of file diff --git a/tzdriver/ion/dynamic_ion_mem.h b/tzdriver/ion/dynamic_ion_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..42169165e69f382a4c23672801012275472d0ab9 --- /dev/null +++ b/tzdriver/ion/dynamic_ion_mem.h @@ -0,0 +1,139 @@ +#ifndef DYNAMIC_MEM_H +#define DYNAMIC_MEM_H + +#include +#include +#include "teek_ns_client.h" + +#ifdef CONFIG_DYNAMIC_ION +#ifdef CONFIG_DMABUF_MM +#include +#else +#include +#endif +#endif + +struct sg_memory { + int dyn_shared_fd; + struct sg_table *dyn_sg_table; + struct dma_buf *dyn_dma_buf; + phys_addr_t ion_phys_addr; + size_t len; + void *ion_virt_addr; +}; + +struct dynamic_mem_item +{ + struct list_head head; + uint32_t configid; + uint32_t size; + struct sg_memory memory; + uint32_t cafd; + struct tc_uuid uuid; + uint32_t ddr_sec_region; +}; + +struct dynamic_mem_config +{ + struct tc_uuid uuid; + uint32_t addr_sec_region; +}; + +#define MAX_ION_NENTS 1024 +typedef struct ion_page_info { + phys_addr_t phys_addr; + uint32_t npages; +}tz_page_info; + +typedef struct sglist { + uint64_t sglist_size; + uint64_t ion_size; + uint64_t ion_id; + uint64_t info_lengtj; + struct ion_page_info page_info[0]; +}tz_sg_list; + +#ifdef CONFIG_DYNAMIC_ION + +bool is_ion_param(uint32_t param_type); +int init_dynamic_mem(void); +int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin); +void kill_ion_by_cafd(unsigned inf cafd); +void kill_ion_by_uuid(const struct tc_uuid *uuid); +int load_image_for_ion(const struct load_img_params *params int32_t *ret_origin); +int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index); +int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index); +#else +static inline bool is_ion_param(uint32_t param_type) +{ + (void)param_type; + return false; +} + +static inline int load_image_for_ion(const struct load_img_params *params, int32_t *ret_origin) +{ + (void)params; + (void)ret_origin; + return 0; +} + +static inline int init_dynamic_mem(void) +{ + return 0; +} + +static inline int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + (void)configid; + (void)cafd; + (void)uuid; + (void)size; + (void)ret_origin; + return 0; +} + +static inline void kill_ion_by_cafd(unsigned int cafd) +{ + (void)cafd; + return; +} + +static inline void kill_ion_by_uuid(const struct tc_uuid *uuid) +{ + (void)uuid; + return; +} + +static inline int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + (void)call_params; + (void)op_params; + (void)kernel_params; + (void)param_type; + (void)index; + tloge("not support seg and related feature!\n"); + return -1; +} + +static inline int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + (void)call_params; + (void)op_params; + (void)kernel_params; + (void)param_type; + (void)index; + tloge("not support seg and related feature!\n"); + return -1; +} +#endif +#endif \ No newline at end of file diff --git a/tzdriver/ion/dynamic_ion_uuid.h b/tzdriver/ion/dynamic_ion_uuid.h new file mode 100644 index 0000000000000000000000000000000000000000..0760a0b54499a33400920706560056597f4e2fb6 --- /dev/null +++ b/tzdriver/ion/dynamic_ion_uuid.h @@ -0,0 +1,74 @@ +#ifndef DYNAMIC_ION_UUID_H +#define DYNAMIC_ION_UUID_H + +#ifdef DEF_ENG +#define TEE_SERVICE_UT \ +{ \ + 0x03030303, \ + 0x0303, \ + 0x0303, \ + { \ + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 \ + }\ +} + +#define TEE_SERVICE_TEST_DYNION \ +{ \ + 0x7f313b2a, \ + 0x68b9, \ + 0x4e92, \ + { \ + 0xac, 0xf9, 0x13, 0x3e, 0xbb, 0x54, 0xeb, 0x56 \ + } \ +} + +#define TEE_SECIDENTIFICATION1 \ +{ \ + 0x8780dda1, \ + 0xa49e, \ + 0x45f4, \ + { \ + 0x96, 0x97, 0xc7, 0xed, 0x9e, 0x38, 0x5e, 0x83 \ + } \ +} + +#define TEE_SECIDENTIFICATION3 \ +{ \ + 0x335129cd, \ + 0x41fa, \ + 0x4b53, \ + { \ + 0x97, 0x97, 0x5c, 0xcb, 0x20, 0x2a, 0x52, 0xd4 \ + } \ +} + +#define TEE_SERVICE_AI \ +{ \ + 0xf4a8816d, \ + 0xb6fb, \ + 0x4d4f, \ + { \ + 0xa2, 0xb9, 0x7d, 0xae, 0x57, 0x33, 0x13, 0xc0 \ + } \ +} + +#define TEE_SERVICE_AI_TINY \ +{ \ + 0xc123c643, \ + 0x5b5b, \ + 0x4c9f, \ + { \ + 0x90, 0x98, 0xbb, 0x09, 0x56, 0x4d, 0x6e, 0xda \ + } \ +} + +#define TEE_SERVICE_VCODEC \ +{ \ + 0x528822b7, \ + 0xfc78, \ + 0x466b, \ + { \ + 0xb5, 0x7e, 0x62, 0x09, 0x3d, 0x60, 0x34, 0xa7 \ + } \ +} +#endif \ No newline at end of file diff --git a/tzdriver/ion/generic/declare_static_ion.c b/tzdriver/ion/generic/declare_static_ion.c new file mode 100644 index 0000000000000000000000000000000000000000..d45fd5b9330515b1c00d834e675bd022620f3621 --- /dev/null +++ b/tzdriver/ion/generic/declare_static_ion.c @@ -0,0 +1,164 @@ +#include "declare_static_ion.h" +#include +#include +#include "tc_ns_log.h" + +static u64 g_ion_mem_addr; +static u64 g_ion_mem_size; + +static int supersonic_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_ion_mem_addr = rmem->base; + g_ion_mem_size = rmem->size; + } else { + tloge("rmem is NULL\n"); + } + + return 0; +} + +RESERVEDMEM_OF_DECLARE(supersonic, "platform-supersonic", + supersonic_reserve_tee_mem); + +static u64 g_secfacedetect_mem_addr; +static u64 g_secfacedetect_mem_size; + +static int secfacedetect_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secfacedetect_mem_addr = rmem->base; + g_secfacedetect_mem_size = rmem->size; + } else { + tloge("secfacedetect_reserve_tee_mem mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secfacedetect, "platform-secfacedetect", + secfacedetect_reserve_tee_mem); + +static u64 g_pt_addr = 0; +static u64 g_pt_size = 0; + +static int reserve_pt_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_pt_size = rmem->size; + g_pt_addr = rmem->base; + } else { + tloge("reserve pt mem is NULL\n"); + } + return 0; +} + +RESERVEDMEM_OF_DECLARE(pagetable, "platform-ai-pagetable", + reserve_pt_mem); + +static u64 g_pp_addr = 0; +static u64 g_pp_size = 0; + +static int reserve_pp_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_pp_addr = rmem->base; + g_pp_size = rmem->size; + } else { + tloge("reserve pp mem is NULL\n"); + } + return 0; +} + +RESERVEDMEM_OF_DECLARE(ai_running, "platform-ai-running", + reserve_pp_mem); + +static u64 g_voiceid_addr = 0; +static u64 g_voiceid_size = 0; +static int voiceid_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_voiceid_addr = rmem->base; + g_voiceid_size = rmem->size; + } else { + tloge("voiceid reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(voiceid, "platform-voiceid", + voiceid_reserve_tee_mem); + +static u64 g_secos_ex_addr; +static u64 g_secos_ex_size; +static int secos_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secos_ex_addr = rmem->base; + g_secos_ex_size = rmem->size; + } else { + tloge("secos reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secos_ex, "platform-secos-ex", + secos_reserve_tee_mem); + +static u64 g_ion_ex_mem_addr; +static u64 g_ion_ex_mem_size; +static int supersonic_ex_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_ion_ex_mem_addr = rmem->base; + g_ion_ex_mem_size = rmem->size; + } else { + tloge("rmem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(supersonic_ex, "platform-supersonic-ex", + supersonic_ex_reserve_tee_mem); + +static void set_mem_tag(struct register_ion_mem_tag *memtag, + u64 addr, u64 size, uint32_t tag, uint32_t *pos) +{ + memtag->memaddr[*pos] = addr; + memtag->memsize[*pos] = size; + memtag->memtag[*pos] = tag; + (*pos)++; +} + +void set_ion_mem_info(struct register_ion_mem_tag *memtag) +{ + uint32_t pos = 0; + if(!memtag) { + tloge("invalid memtag\n"); + return; + } + + tlogi("ion mem static reserved for tee face=%d, finger=%d,voiceid=%d" + "secos=%d,finger-ex=%d, pt_size= %d,pp_size=%d\n", + (uint32_t)g_secfacedetect_mem_size, (uint32_t)g_ion_mem_size, + (uint32_t)g_voiceid_size, (uint32_t)g_secos_ex_size, + (uint32_t)g_ion_ex_mem_size, (uint32_t)g_pt_size, + (uint32_t)g_pp_size); + + if (g_ion_mem_addr != (u64)0 && g_ion_mem_size != (u64)0) + set_mem_tag(memtag,g_ion_mem_addr, g_ion_mem_size, PP_MEM_TAG, &pos); + if (g_secfacedetect_mem_addr != (u64)0 && g_secfacedetect_mem_size != (u64)0) + set_mem_tag(memtag,g_secfacedetect_mem_addr, g_secfacedetect_mem_size, PP_MEM_TAG, &pos); + if (g_voiceid_addr != (u64)0 && g_voiceid_size != (u64)0) + set_mem_tag(memtag, g_voiceid_addr, g_voiceid_size, PP_MEM_TAG, &pos); + if (g_secos_ex_addr != (u64)0 && g_secos_ex_size != (u64)0) + set_mem_tag(memtag, g_secos_ex_addr, g_secos_ex_size, PP_MEM_TAG, &pos); + if (g_pt_addr != (u64)0 && g_pt_size != (u64)0) + set_mem_tag(memtag, g_pt_addr, g_pt_size, PT_MEM_TAG, &pos); + if (g_pp_addr != (u64)0 && g_pp_size != (u64)0) + set_mem_tag(memtag, g_pp_addr, g_pp_size, PRI_PP_MEM_TAG, &pos); + if (g_ion_ex_mem_addr != (u64)0 && g_ion_ex_mem_size != (u64)0) + set_mem_tag(memtag, g_ion_ex_mem_addr, g_ion_ex_mem_size, PP_MEM_TAG, &pos); + /* here pos max is 7, memaddr[] has 10 positions, just 3 free */ + memtag->size = pos; + return; +} \ No newline at end of file diff --git a/tzdriver/ion/mplat/declare_static_ion.c b/tzdriver/ion/mplat/declare_static_ion.c new file mode 100644 index 0000000000000000000000000000000000000000..8a1bb0c6f94b831358c4e55b87aedb35a9d87006 --- /dev/null +++ b/tzdriver/ion/mplat/declare_static_ion.c @@ -0,0 +1,39 @@ +#include "declare_static_ion.h" +#include +#include +#include "tc_ns_log.h" + +static u64 g_secos_ex_addr; +static u64 g_secos_ex_size; +static int secos_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secos_ex_addr = rmem->base; + g_secos_ex_size = rmem->size; + } else { + tloge("secos reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secos_ex, "mediatek,tee_os_reserved_memory", + secos_reserve_tee_mem); + +void set_ion_mem_info(struct register_ion_mem_tag *memtag) +{ + uint32_t pos = 0; + if(!memtag) { + tloge("invalid memtag\n"); + return; + } + + tlogi("ion mem static reserved for tee secos=%d\n", (uint32_t)g_secos_ex_size); + + if (g_secos_ex_addr != (u64)0 && g_secos_ex_size != (u64)0) { + memtag->memaddr[pos] = g_secos_ex_addr; + memtag->memsize[pos] = g_secos_ex_size; + memtag->memtag[pos] = PP_MEM_TAG; + pos++; + } + memtag->size = pos; + return; +} \ No newline at end of file diff --git a/tzdriver/ion/static_ion_mem.c b/tzdriver/ion/static_ion_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..0ef94c44945a356528c6bc731f0eb1b871b9dccd --- /dev/null +++ b/tzdriver/ion/static_ion_mem.c @@ -0,0 +1,53 @@ +#include "static_ion_mem.h" +#include +#include +#include +#include +#include +#ifdef DEF_ENG +#include +#include +#endif +#include "smc_smp.h" +#include "teek_ns_client.h" +#include "mailbox_mempool.h" +#include "tc_ns_log.h" +#include "declare_static_ion.h" + +/* send the ion static memory to tee */ +int tc_ns_register_ion_mem(void) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + int ret = 0; + struct mb_cmd_pack *mb_pack = NULL; + struct register_ion_mem_tag *memtag = NULL; + + mb_pack = mailbox_alloc_cmd_pack(); + if (!mb_pack) { + tloge("mailbox alloc failed\n"); + return -ENOMEM; + } + set_ion_mem_info(memtag); + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_ION_MEM; + + mb_pack->operation.paramtypes = TEE_PARAM_TYPE_MEMREF_INPUT; + mb_pack->operation.params[0].memref.buffer = + maibox_virt_to_phys((uintptr_t)(void *)memtag); + mb_pack->operation.buffer_h_addr[0] = + (uint64_t)maibox_virt_to_phys((uintptr_t)(void *)memtag) >> ADDR_TRANS_NUM; + mb_pack->operation.params[0].memref.size = sizeof(*memtag); + + smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = + (uint64_t)maibox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; + + if (tc_ns_smc(&smc_cmd)) { + ret = -EPERM; + tloge("send ion mem info failed\n"); + } + mailbox_free(mb_pack); + mailbox_free(memtag); + + return ret; +} \ No newline at end of file diff --git a/tzdriver/ion/static_ion_mem.h b/tzdriver/ion/static_ion_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..93304684532912629bd6980a975b9a50c8f24f2c --- /dev/null +++ b/tzdriver/ion/static_ion_mem.h @@ -0,0 +1,31 @@ +#ifndef STATIC_ION_MEM_H +#define STATIC_ION_MEM_H +#include + +#define ION_MEM_MAX_SIZE 10 + +struct register_ion_mem_tag { + uint32_t size; + uint64_t memaddr[ION_MEM_MAX_SIZE]; + uint32_t memsize[ION_MEM_MAX_SIZE]; + uint32_t memtag[ION_MEM_MAX_SIZE]; +}; + +enum static_mem_tag { + MEM_TAG_MIN = 0, + PP_MEM_TAG = 1, + PRI_PP_MEM_TAG = 2, + PT_MEM_TAG = 3, + MEM_TAG_MAX, +}; + +#ifdef CONFIG_STATIC_ION +int tc_ns_register_ion_mem(void); +#else +static inline int tc_ns_register_ion_mem(void) +{ + return 0; +} +#endif + +#endif \ No newline at end of file diff --git a/tzdriver/whitelist/Makefile b/tzdriver/whitelist/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d3d8bc5cb85c77e9491089b32d63d411fcf9725a --- /dev/null +++ b/tzdriver/whitelist/Makefile @@ -0,0 +1,13 @@ +KERNEL_DIR := $(srctree) + +ifneq ($(TARGET_BUILD_VARIANT), user) + ccflags-y += -DDEF_ENG +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/include +EXTRA_CFLAGS += include internal_functions.h + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/core + +obj-y += agent_allowed_ca.o \ No newline at end of file diff --git a/tzdriver/whitelist/agent_allocwed_ca.c b/tzdriver/whitelist/agent_allocwed_ca.c new file mode 100644 index 0000000000000000000000000000000000000000..359b093d9db1b6ed45b64ffca824a19f22dab529 --- /dev/null +++ b/tzdriver/whitelist/agent_allocwed_ca.c @@ -0,0 +1,67 @@ +#include "agent.h" +#include +#include +#include + +static struct ca_info g_allowed_ext_agent_ca[] = { +#ifdef CONFIG_TZDRIVER + { + "/vendor/bin/hiaiserver", + 3094, + TEE_SECE_AGENT_ID, + }, + { + "/vendor/bin/hw/vendor.huawei.hardware.\ + biometrics.hwfacerecognize@1.1-service", + 1000, + TEE_FACE_AGENT1_ID, + }, + { + "/vendor/bin/hw/vendor.huawei.hardware.\ + biometrics.hwfacerecognize@1.1-service", + 1000, + TEE_FACE_AGENT2_ID, + }, +#endif +#ifdef DEF_ENG + { + "vendor/bin/tee_test_agent", + 0, + TEE_SECE_AGENT_ID, + }, +#endif +}; + +int is_allowed_agent_ca(const struct ca_info *ca, + bool check_agent_id) +{ + uint32_t i; + struct ca_info *tmp_ca = g_allowed_ext_agent_ca; + const uint32_t nr = ARRAY_SIZE(g_allowed_ext_agent_ca); + + if (!ca) + return -EFAULT; + + if (!check_agent_id) { + for (i = 0; i < nr; i++) { + if (!strncmp(ca->path, tmp_ca->path, + strlen(tmp_ca->path) + 1) && + ca->uid == tmp_ca->uid) + return 0; + tmp_ca++; + } + } else { + for (i = 0; i < nr; i++) { + if (!strncmp(ca->path, tmp_ca->path, + strlen(tmp_ca->path) + 1) && + ca->uid == tmp_ca->uid && + ca->agent_id == tmp_ca->agent_id) + return 0; + tmp_ca++; + } + } + tlogd("ca-uid is %u, ca_path is %s, agent id is %x\n", ca->uid, + ca->path, ca->agent_id); + + return -EACCES; +} \ No newline at end of file diff --git a/tzdriver1/ion/Kconfig b/tzdriver1/ion/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..dae0cecc5e400149e2fb8f7eaf8f29e6e870bc4c --- /dev/null +++ b/tzdriver1/ion/Kconfig @@ -0,0 +1,13 @@ +config DYNAMIC_ION + bool "Dynamic Ion Feature" + default n + depends on TZDRIVER + help + TEEOS dynamic ion + +config STATIC_ION + bool "Static Ion Feature" + default n + depends on TZDRIVER + help + TEEOS static ion \ No newline at end of file diff --git a/tzdriver1/ion/Makefile b/tzdriver1/ion/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cf4b92e8d167edbc29d7cd193fedd06196830cde --- /dev/null +++ b/tzdriver1/ion/Makefile @@ -0,0 +1,20 @@ +KERNEL_DIR :=$(srctree) + +ifneq ($(TARGET_BUILD_VARIANT),user) + ccflags-y += -DDEF_ENG +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/core +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/staging/android + +obj-$(CONFIG_STATIC_ION) += static_ion_mem.o +obj-$(CONFIG_DYNAMIC_ION) += dynamic_ion_mem.o +ifneq ($(CONFIG_MTK_PLATFORM), ) + obj-$(CONFIG_STATIC_ION) += mplat/declare_static_ion.o +else + obj-$(CONFIG_STATIC_ION) += generic/declare_static_ion.o +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/include +EXTRA_CFLAGS += -include internal_functions.h \ No newline at end of file diff --git a/tzdriver1/ion/declare_static_ion.h b/tzdriver1/ion/declare_static_ion.h new file mode 100644 index 0000000000000000000000000000000000000000..1632479d6589f5500e561f3d5b5311c4540929f0 --- /dev/null +++ b/tzdriver1/ion/declare_static_ion.h @@ -0,0 +1,7 @@ +#ifndef DECLARE_STATIC_ION_H +#define DECLARE_STATIC_ION_H +#include "static_ion_mem.h" + +void set_ion_mem_info(struct register_ion_mem_tag *memtag); + +#endif \ No newline at end of file diff --git a/tzdriver1/ion/dynamic_ion_mem.c b/tzdriver1/ion/dynamic_ion_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..a49170b9f901ff70e7828208ccb48e8b7f92fec3 --- /dev/null +++ b/tzdriver1/ion/dynamic_ion_mem.c @@ -0,0 +1,639 @@ +#include "dynamic_ion_mem.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CONFIG_DMABUF_MM +#include +#endif +#include +#include +#include +#include +#if ((defined CONFIG_ION_MM) || (defined CONFIG_ION_MM_SECSG)) +#include +#endif +#ifdef CONFIG_DMABUF_MM +#include +#endif +#include "tc_ns_log.h" +#include "tc_ns_client.h" +#include "smc_smp.h" +#include "gp_ops.h" +#include "teek_client_constants.h" +#include "mailbox_mempool.h" +#include "dynamic_ion_uuid.h" + +static DEFINE_MUTEX(dynamic_mem_lock); +struct dynamic_mem_list { + struct list_head list; +}; + +static const struct dynamic_mem_config g_dyn_mem_config[] = { + #ifdef DEF_ENG + {TEE_SERVICE_UT, SEC_EID}, + {TEE_SERVICE_TEST_DYNION, SEC_AI_ION}, + #endif + {TEE_SECIDENTIFICATION1, SEC_EID}, + {TEE_SECIDENTIFICATION3, SEC_EID}, + {TEE_SERVICE_AI, SEC_AI_ION}, + {TEE_SERVICE_AI_TINY, SEC_AI_ION}, + {TEE_SERVICE_VCODEC, SEC_DRM_TEE}, +}; + +static struct dynamic_mem_list g_dynamic_mem_list; +static const uint32_t g_dyn_mem_config_num = ARRAY_SIZE(g_dyn_mem_config); + +static int release_ion_srv(const struct tc_uuid *uuid) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + + smc_cmd.err_origin = TEEC_ORIGIN_COMMS; + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = GLOBAL_CMD_ID_RELEASE_ION_SRV; + if (memcpy_s(&smc_cmd.uuid, sizeof(smc_cmd.uuid), uuid, sizeof(*uuid))) { + tloge("copy uuid failed\n"); + return -ENOMEM; + } + + if (tc_ns_smc(&smc_cmd)) { + tloge("send release ion srv cmd failed\n"); + return -EPERM; + } + return 0; +} + + +static int get_ion_sglist(struct dynamic_mem_item *mem_item) +{ + struct sglist *tmp_sglist = NULL; + struct scatterlist *sg = NULL; + struct page *page = NULL; + uint32_t sglist_size; + uint32_t i = 0; + struct sg_table *ion_sg_table = mem_item->memory.dyn_sg_table; + + if (!ion_sg_table) + return -EINVAL; + + if (ion_sg_table->nents <= 0 || ion_sg_table->nents > MAX_ION_NENTS) + return -EINVAL; + + for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) { + if (!sg) { + tloge("an error sg when get ion sglist\n"); + return -EINVAL; + } + } + + sglist_size = sizeof(struct ion_page_info) * ion_sg_table->nents + sizeof(*tmp_sglist); + tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO); + if (!tmp_sglist) { + tloge("mailbox alloc failed\n"); + return -ENOMEM; + } + + tmp_sglist->sglist_size = (uint64_t)sglist_size; + tmp_sglist->ion_size = (uint64_t)mem_item->size; + tmp_sglist->info_length = (uint64_t)ion_sg_table->nents; + for_each_sg(ion_sg_table->sgl, sg, ion_sg_table->nents, i) { + page = sg_page(sg); + tmp_sglist->page_info[i].phys_addr = page_to_phys(page); + tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE; + } + mem_item->memory.ion_phys_addr = mailbox_virt_to_phys((uintptr_t)(void *)tmp_sglist); + mem_item->memory.len = sglist_size; + return 0; +} + +static int send_dyn_ion_cmd(struct dynamic_mem_item *mem_item, unsigned int cmd_id, int32_t *ret_origin) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + int ret; + struct mb_cmd_pack *mb_pack = NULL; + + if (!mem_item) { + tloge("mem_item is null\n"); + return -EINVAL; + } + + ret = get_ion_sglist(mem_item); + if (ret != 0) + return ret; + + mb_pack = mailbox_alloc_cmd_pack(); + if (!mb_pack) { + mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr)); + tloge("alloc cmd pack failed\n"); + return -ENOMEM; + } + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = cmd_id; + smc_cmd.err_origin = TEEC_ORIGIN_COMMS; + mb_pack->operation.paramtypes = teec_param_types( + TEE_PARAM_TYPE_ION_SGLIST_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_VALUE_INPUT, + TEE_PARAM_TYPE_NONE); + + mb_pack->operation.params[0].memref.size = (uint32_t)mem_item->memory.len; + mb_pack->operation.params[0].memref.buffer = + (uint32_t)(mem_item->memory.ion_phys_addr & 0xFFFFFFFF); + mb_pack->operation.buffer_h_addr[0] = + (uint64_t)(mem_item->memory.ion_phys_addr) >> ADDR_TRANS_NUM; + mb_pack->operation.params[1].value.a = (uint32_t)mem_item->size; + mb_pack->operation.params[2].value.a = mem_item->configid; + smc_cmd.operation_phys = (unsigned int)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; + + if (tc_ns_smc(&smc_cmd)) { + if (ret_origin) + *ret_origin = smc_cmd.err_origin; + ret = -EPERM; + tlogd("send loadapp ion failed\n"); + } + mailbox_free(phys_to_virt(mem_item->memory.ion_phys_addr)); + mailbox_free(mb_pack); + return ret; +} + +static struct dynamic_mem_item *find_memitem_by_configid_locked(uint32_t configid) +{ + struct dynamic_mem_item *item = NULL; + list_for_each_entry(item, &g_dynamic_mem_list.list, head) { + if (item->configid == configid) + return item; + } + return NULL; +} + +static struct dynamic_mem_item *find_memitem_by_uuid_locked(const struct tc_uuid *uuid) +{ + struct dynamic_mem_item *item = NULL; + list_for_each_entry(item, &g_dynamic_mem_list.list, head) { + if (!memcmp(&item->uuid, uuid, sizeof(*uuid))) + return item; + } + return NULL; +} + +#define BLOCK_64KB_SIZE (64 * 1024) /* 64 */ +#define BLOCK_64KB_MASK 0xFFFFFFFFFFFF0000 +/* size should be aligned with 64KB */ +#define BLOCK_64KB_SIZE_MASK (BLOCK_64KB_SIZE -1) +static int proc_alloc_dyn_mem(struct dynamic_mem_item *mem_item) +{ + struct sg_table *ion_sg_table = NULL; + + if (mem_item->size + BLOCK_64KB_SIZE_MASK < mem_item->size) { + tloge("ion size is error, size = %x\n", mem_item->size); + return _EINVAL; + } + mem_item->memory.len = (mem_item ->size + BLOCK_64KB_SIZE_MASK) & BLOCK_64KB_MASK; + + ion_sg_table = mm_secmem_alloc(mem_item->addr_sec_region, + mem_item->memory.len); + if (!ion_sg_table) { + tloge("failed to get ion page, configid = %d\n", + mem_item->configid); + return _ENOMEM; + } + mem_item->memory.dyn_sg_table = ion_sg_table; + return 0; +} + +static void proc_free_dyn_mem(struct dynamic_mem_item *mem_item) +{ + if (!mem_item->memory.dyn_sg_table) { + tloge("ion_phys_addr is NULL\n"); + return; + } + mm_secmem_free(mem_item->ddr_sec_region, + mem_item->memory.dyn_sg_table); + mem_item->memory.dyn_sg_table = NULL; + return; +} + +int init_dynamic_mem(void) +{ + INIT_LIST_HEAD(&(g_dynamic_mem_list.list)); + return 0; +} + +static int32_t find_ddr_sec_region_by_uuid(const struct tc_uuid *uuid, + uint32_t *ddr_sec_region) +{ + uint32_t i; + for (i = 0; i < g_dyn_mem_config_num; i++) { + if (!memcmp(&(g_dyn_mem_config[i].uuid), uuid, + sizeof(*uuid))) { + *ddr_sec_region = g_dyn_mem_config[i].ddr_sec_region; + return 0; + } + } + return -EINVAL; +} + +static struct dynamic_mem_item *alloc_dyn_mem_item(uint32_t configid, + uint32_t cafd, const struct tc_uuid *uuid, uint32_t size) +{ + uint32_t ddr_sec_region; + struct dynamic_mem_item *mem_item = NULL; + int32_t result; + + result = find_ddr_sec_region_by_uuid(uuid, &ddr_sec_region); + if (result != 0) { + tloge("find ddr sec region failed\n"); + return NULL; + } + + mem_item = kzalloc(sizeof(*mem_item), GFP_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)mem_item)) { + tloge("alloc mem item failed\n"); + return NULL; + } + + mem_item->ddr_sec_region = ddr_sec_region; + mem_item->configid = configid; + mem_item->size = size; + mem_item->cafd = cafd; + result = memcpy_s(&mem_item->uuid, sizeof(mem_item->uuid), uuid, + sizeof(*uuid)); + if(result != EOK) { + tloge("memcpy uuid failed\n"); + kfree(mem_item); + return NULL; + } + return mem_item; +} + + +static int trans_configid2memid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + int result; + + if (!uuid) + return -EINVAL; + mutex_lock(&dynamic_mem_lock); + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_configid_locked(configid); + if (mem_item) { + result = -EINVAL; + break; + } + + mem_item = alloc_dyn_mem_item(configid, cafd, uuid, size); + if (!mem_item) { + tloge("alloc dyn mem item failed\n"); + result = -ENOMEM; + break; + } + + result = proc_alloc_dyn_mem(mem_item); + if (result != 0) { + tloge("alloc dyn mem failed , ret = %d\n", result); + kfree(mem_item); + break; + } + /* register to tee */ + result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_DEL_DYNAMIC_ION, ret_origin); + if (result != 0) { + tloge("register to tee failed, result = %d\n", result); + proc_free_dyn_mem(mem_item); + kfree(mem_item); + break; + } + list_add_tail(&mem_item->head, &g_dynamic_mem_list.list); + tloge("log import:alloc ion configid=%d\n", + mem_item->configid); + } while (0); + + mutex_unlock(&dynamic_mem_lock); + return result; +} + +static void release_configid_mem_locked(uint32_t configid) +{ + int result; + /* if config id is memid map, and can reuse */ + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_configid_locked(configid); + if (!mem_item) { + tloge("fail to find memitem by configid\n"); + break; + } + + result = send_dyn_ion_cmd(mem_item, GLOBAL_CMD_ID_ADD_DYNAMIC_ION, NULL); + if (result != 0) { + tloge("unregister_from_tee configid=%d, result =%d\n", + mem_item->configid, result); + break; + } + proc_free_dyn_mem(mem_item); + list_del(&mem_item->head); + kfree(mem_item); + tloge("log import: free ion\n"); + } while (0); + + return; +} + + +int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + int result; + + if (!uuid) + return -EINVAL; + + result = trans_configid2memid(configid, cafd, uuid, size, ret_origin); + if (result != 0) { + tloge("trans_configid2memid failed ret = %d\n", result); + if (release_ion_srv(uuid) != 0) + tloge("release ion srv failed\n"); + } + return result; +} + + +void kill_ion_by_uuid(const struct tc_uuid *uuid) +{ + if (!uuid) { + tloge("uuid is null\n"); + return; + } + mutex_lock(&dynamic_mem_lock); + do { + struct dynamic_mem_item *mem_item = + find_memitem_by_uuid_locked(uuid); + if (!mem_item) + break; + tlogd("kill ION by UUID\n"); + release_configid_mem_locked(mem_item->configid); + } while (0); + mutex_unlock(&dynamic_mem_lock); +} + +void kill_ion_by_cafd(unsigned int cafd) +{ + struct dynamic_mem_item *item = NULL; + struct dynamic_mem_item *temp = NULL; + tlogd("kill_ion_by_cafd:\n"); + mutex_lock(&dynamic_mem_lock); + list_for_each_entry_safe(item, temp, &g_dynamic_mem_list.list, head) { + if (item->cafd == cafd) + release_configid_mem_locked(item->configid); + } + mutex_unlock(&dynamic_mem_lock); +} + +int load_image_for_ion(const struct load_img_params *params, int32_t *ret_origin) +{ + int ret = 0; + + if (!params) + return -EFAULT; + /* check need to add ionmem */ + uint32_t configid = params->mb_pack->operation.params[1].value.a; + uint32_t ion_size = params->mb_pack->operation.params[1].value.b; + int32_t check_result = (configid != 0 && ion_size != 0); + + tloge("check load result=%d, cfgid=%d, ion_size=%d, uuid=%x\n", + check_result, configid, ion_size, params->uuid_return->time_low); + if (check_result) { + ret = load_app_use_configid(configid, params->dev_file->dev_file_id, + params->uuid_return, ion_size, ret_origin); + if (ret != 0) { + tloge("load app use configid failed ret=%d\n", ret); + return -EFAULT; + } + } + return ret; +} + +bool is_ion_param(uint32_t param_type) +{ + if (param_type == TEEC_ION_INPUT || + param_type == TEEC_ION_SGLIST_INPUT) + return true; + return false; +} + +static void fill_sg_list(struct sg_table *ion_table, + uint32_t ion_list_num, struct sglist *tmp_sglist) +{ + uint32_t i; + struct page *page = NULL; + struct scatterlist *sg = NULL; + + for_each_sg(ion_table->sgl, sg, ion_list_num, i) { + page = sg_page(sg); + tmp_sglist->page_info[i].phys_addr = page_to_phys(page); + tmp_sglist->page_info[i].npages = sg->length / PAGE_SIZE; + } +} + +static int check_sg_list(const struct sg_table *ion_table, uint32_t ion_list_num) +{ + struct scatterlist *sg = NULL; + uint32_t i; + for_each_sg(ion_table->sgl, sg, ion_list_num, i) { + if (!sg) { + tloge("an error sg when get ion sglist \n"); + return -EFAULT; + } + } + return 0; +} + +static int get_ion_sg_list_from_fd(uint32_t ion_shared_fd, + uint32_t ion_alloc_size, phys_addr_t *sglist_table, + size_t *ion_sglist_size) +{ + struct sg_table *ion_table = NULL; + struct sglist *tmp_sglist = NULL; + uint64_t ion_id = 0; + enum SEC_SVC ion_type = 0; + uint32_t ion_list_num = 0; + uint32_t sglist_size; +#ifdef CONFIG_DMABUF_MM + if (mm_dma_heap_secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) { +#else + if (secmem_get_buffer(ion_shared_fd, &ion_table, &ion_id, &ion_type)) { +#endif + tloge("get ion table failed. \n"); + return -EFAULT; + } + + if (ion_type != SEC_DRM_TEE) { + if (ion_table->nents <= 0 || ion_table->nents > MAX_ION_NENTS) + return -EFAULT; + ion_list_num = (uint32_t)(ion_table->nents & INT_MAX); + if (check_sg_list(ion_table, ion_list_num) != 0) + return -EFAULT; + } + /* ion_list_num is less than 1024, so sglist_size won't flow */ + sglist_size = sizeof(struct ion_page_info) * ion_list_num + sizeof(*tmp_sglist); + tmp_sglist = (struct sglist *)mailbox_alloc(sglist_size, MB_FLAG_ZERO); + if (!tmp_sglist) { + tloge("sglist mem alloc failed\n"); + return -ENOMEM; + } + tmp_sglist->sglist_size = (uint64_t)sglist_size; + tmp_sglist->ion_size = (uint64_t)ion_alloc_size; + tmp_sglist->info_length = (uint64_t)ion_list_num; + if (ion_type != SEC_DRM_TEE) + fill_sg_list(ion_table, ion_list_num, tmp_sglist); + else + tmp_sglist->ion_id = ion_id; + + *sglist_table = mailbox_virt_to_phys((uintptr_t)tmp_sglist); + *ion_sglist_size = sglist_size; + return 0; +} + +int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + struct tc_ns_operation *operation = NULL; + size_t ion_sglist_size = 0; + phys_addr_t ion_sglist_addr = 0x0; + union tc_ns_client_param *client_param = NULL; + unsigned int ion_shared_fd = 0; + unsigned int ion_alloc_size; + uint64_t a_addr, b_addr; + + /* this never happens */ + if (index >= TEE_PARAM_NUM || !call_params || !op_params) + return -EINVAL; + + operation = &op_params->mb_pack->operation; + client_param = &(call_params->context->params[index]); + a_addr = client_param->value.a_addr | + ((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM); + b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + + if (read_from_client(&operation->params[index].value.a, + sizeof(operation->params[index].value.a), + (void *)(uintptr_t)a_addr, + sizeof(operation->params[index].value.a), kernel_params)) { + tloge("valuea copy failed\n"); + return -EFAULT; + } + if (read_from_client(&operation->params[index].value.b, + sizeof(operation->params[index].value.b), + (void *)(uintptr_t)b_addr, + sizeof(operation->params[index].value.b), kernel_params)) { + tloge("valueb copy failed\n"); + return -EFAULT; + } + ion_shared_fd = operation->params[index].value.a; + ion_alloc_size = operation->params[index].value.b; + + if(get_ion_sg_list_from_fd(ion_shared_fd, ion_alloc_size, + &ion_sglist_addr, &ion_sglist_size)) { + tloge("get ion sglist failed, fd=%u\n", ion_shared_fd); + return -EFAULT; + } + op_params->local_tmpbuf[index].temp_buffer = phys_to_virt(ion_sglist_addr); + op_params->local_tmpbuf[index].size = ion_sglist_size; + + operation->params[index].memref.buffer = (unsigned int)ion_sglist_addr; + operation->buffer_h_addr[index] = + (uint64_t)ion_sglist_addr >> ADDR_TRANS_NUM; + operation->params[index].memref.size = (unsigned int)ion_sglist_size; + op_params->trans_paramtype[index] = param_type; + + return 0; +} + +static int transfer_ion_params(struct tc_ns_operation *operation, + union tc_ns_client_param *client_param, uint8_t kernel_params, + unsigned int index) +{ + uint64_t a_addr = client_param->value.a_addr | + ((uint64_t)client_param->value.a_h_addr << ADDR_TRANS_NUM); + uint64_t b_addr = client_param->value.b_addr | + ((uint64_t)client_param->value.b_h_addr << ADDR_TRANS_NUM); + + if (read_from_client(&operation->params[index].value.a, + sizeof(operation->params[index].value.a), + (void *)(uintptr_t)a_addr, + sizeof(operation->params[index].value.a), kernel_params)) { + tloge("value.a_addr copy failed\n"); + return -EFAULT; + } + + if (read_from_client(&operation->params[index].value.b, + sizeof(operation->params[index].value.b), + (void *)(uintptr_t)b_addr, + sizeof(operation->params[index].value.b), kernel_params)) { + tloge("value.b_addr copy failed\n"); + return -EFAULT; + } + + return 0; +} + +int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + struct tc_ns_operation *operation = NULL; + size_t drm_ion_size = 0; + phys_addr_t drm_ion_phys = 0x0; + struct dma_buf *drm_dma_buf = NULL; + union tc_ns_client_param *client_param = NULL; + unsigned int ion_shared_fd = 0; + int ret = 0; + + /* this never happens */ + if (index >= TEE_PARAM_NUM || !call_params || !op_params) + return -EINVAL; + + operation = &op_params->mb_pack->operation; + client_param = &(call_params->context->params[index]); + if (transfer_ion_params(operation, client_param, kernel_params, index)) + return -EFAULT; + + ion_shared_fd = operation->params[index].value.a; + drm_dma_buf = dma_buf_get(ion_shared_fd); + if (IS_ERR_OR_NULL(drm_dma_buf)) { + tloge("drm dma buf is err, ret = %d fd = %u\n", ret, ion_shared_fd); + return -EFAULT; + } +#ifdef CONFIG_DMABUF_MM + ret = mm_dma_heap_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size); +#else + ret = ion_secmem_get_phys(drm_dma_buf, &drm_ion_phys, &drm_ion_size); +#endif + if (ret != 0) { + tloge("in %s err:ret=%d fd=%u\n", __func__, ret, ion_shared_fd); + dma_buf_put(drm_dma_buf); + return -EFAULT; + } + + if (drm_ion_size > operation->params[index].value.b) + drm_ion_size = operation->params[index].value.b; + operation->params[index].value.a = (unsigned int)drm_ion_phys; + operation->params[index].value.b = (unsigned int)drm_ion_size; + op_params->trans_paramtype[index] = param_type; + dma_buf_put(drm_dma_buf); + + return ret; +} \ No newline at end of file diff --git a/tzdriver1/ion/dynamic_ion_mem.h b/tzdriver1/ion/dynamic_ion_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..06db17d5c9621600a3fc034e91990b2f2c311309 --- /dev/null +++ b/tzdriver1/ion/dynamic_ion_mem.h @@ -0,0 +1,139 @@ +#ifndef DYNAMIC_MMEM_H +#define DYNAMIC_MMEM_H + +#include +#include +#include "teek_ns_client.h" + +#ifdef CONFIG_DYNAMIC_ION +#ifdef CONFIG_DMABUF_MM +#include +#else +#include +#endif +#endif + +struct sg_memory { + int dyn_shared_fd; + struct sg_table *dyn_sg_table; + struct dma_buf *dyn_dma_buf; + phys_addr_t ion_phys_addr; + size_t len; + void *ion_virt_addr; +}; + +struct dynamic_mem_item +{ + struct list_head head; + uint32_t configid; + uint32_t size; + struct sg_memory memory; + uint32_t cafd; + struct tc_uuid uuid; + uint32_t ddr_sec_region; +}; + +struct dynamic_mem_config +{ + struct tc_uuid uuid; + uint32_t ddr_sec_region; +}; + +#define MAX_ION_NENTS 1024 +typedef struct ion_page_info { + phys_addr_t phys_addr; + uint32_t npages; +}tz_page_info; + +typedef struct sglist { + uint64_t sglist_size; + uint64_t ion_size; + uint64_t ion_id; + uint64_t info_length; + struct ion_page_info page_info[0]; +}tz_sg_list; + +#ifdef CONFIG_DYNAMIC_ION + +bool is_ion_param(uint32_t param_type); +int init_dynamic_mem(void); +int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin); +void kill_ion_by_cafd(unsigned int cafd); +void kill_ion_by_uuid(const struct tc_uuid *uuid); +int load_image_for_ion(const struct load_img_params *params int32_t *ret_origin); +int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index); +int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index); +#else +static inline bool is_ion_param(uint32_t param_type) +{ + (void)param_type; + return false; +} + +static inline int load_image_for_ion(const struct load_img_params *params, int32_t *ret_origin) +{ + (void)params; + (void)ret_origin; + return 0; +} + +static inline int init_dynamic_mem(void) +{ + return 0; +} + +static inline int load_app_use_configid(uint32_t configid, uint32_t cafd, + const struct tc_uuid *uuid, uint32_t size, int32_t *ret_origin) +{ + (void)configid; + (void)cafd; + (void)uuid; + (void)size; + (void)ret_origin; + return 0; +} + +static inline void kill_ion_by_cafd(unsigned int cafd) +{ + (void)cafd; + return; +} + +static inline void kill_ion_by_uuid(const struct tc_uuid *uuid) +{ + (void)uuid; + return; +} + +static inline int alloc_for_ion_sglist(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + (void)call_params; + (void)op_params; + (void)kernel_params; + (void)param_type; + (void)index; + tloge("not support seg and related feature!\n"); + return -1; +} + +static inline int alloc_for_ion(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + (void)call_params; + (void)op_params; + (void)kernel_params; + (void)param_type; + (void)index; + tloge("not support ion and related feature!\n"); + return -1; +} +#endif +#endif \ No newline at end of file diff --git a/tzdriver1/ion/dynamic_ion_uuid.h b/tzdriver1/ion/dynamic_ion_uuid.h new file mode 100644 index 0000000000000000000000000000000000000000..356d56f89ec21fdbef0658ac487f5a05c0e2d5b4 --- /dev/null +++ b/tzdriver1/ion/dynamic_ion_uuid.h @@ -0,0 +1,75 @@ +#ifndef DYNAMIC_ION_UUID_H +#define DYNAMIC_ION_UUID_H + +#ifdef DEF_ENG +#define TEE_SERVICE_UT \ +{ \ + 0x03030303, \ + 0x0303, \ + 0x0303, \ + { \ + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 \ + }\ +} + +#define TEE_SERVICE_TEST_DYNION \ +{ \ + 0x7f313b2a, \ + 0x68b9, \ + 0x4e92, \ + { \ + 0xac, 0xf9, 0x13, 0x3e, 0xbb, 0x54, 0xeb, 0x56 \ + } \ +} +#endif + +#define TEE_SECIDENTIFICATION1 \ +{ \ + 0x8780dda1, \ + 0xa49e, \ + 0x45f4, \ + { \ + 0x96, 0x97, 0xc7, 0xed, 0x9e, 0x38, 0x5e, 0x83 \ + } \ +} + +#define TEE_SECIDENTIFICATION3 \ +{ \ + 0x335129cd, \ + 0x41fa, \ + 0x4b53, \ + { \ + 0x97, 0x97, 0x5c, 0xcb, 0x20, 0x2a, 0x52, 0xd4 \ + } \ +} + +#define TEE_SERVICE_AI \ +{ \ + 0xf4a8816d, \ + 0xb6fb, \ + 0x4d4f, \ + { \ + 0xa2, 0xb9, 0x7d, 0xae, 0x57, 0x33, 0x13, 0xc0 \ + } \ +} + +#define TEE_SERVICE_AI_TINY \ +{ \ + 0xc123c643, \ + 0x5b5b, \ + 0x4c9f, \ + { \ + 0x90, 0x98, 0xbb, 0x09, 0x56, 0x4d, 0x6e, 0xda \ + } \ +} + +#define TEE_SERVICE_VCODEC \ +{ \ + 0x528822b7, \ + 0xfc78, \ + 0x466b, \ + { \ + 0xb5, 0x7e, 0x62, 0x09, 0x3d, 0x60, 0x34, 0xa7 \ + } \ +} +#endif \ No newline at end of file diff --git a/tzdriver1/ion/generic/declare_static_ion.c b/tzdriver1/ion/generic/declare_static_ion.c new file mode 100644 index 0000000000000000000000000000000000000000..64a1ec370352be030601f0f2eda924a66a20e943 --- /dev/null +++ b/tzdriver1/ion/generic/declare_static_ion.c @@ -0,0 +1,164 @@ +#include "declare_static_ion.h" +#include +#include +#include "tc_ns_log.h" + +static u64 g_ion_mem_addr; +static u64 g_ion_mem_size; + +static int supersonic_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_ion_mem_addr = rmem->base; + g_ion_mem_size = rmem->size; + } else { + tloge("rmem is NULL\n"); + } + + return 0; +} + +RESERVEDMEM_OF_DECLARE(supersonic, "platform-supersonic", + supersonic_reserve_tee_mem); + +static u64 g_secfacedetect_mem_addr; +static u64 g_secfacedetect_mem_size; + +static int secfacedetect_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secfacedetect_mem_addr = rmem->base; + g_secfacedetect_mem_size = rmem->size; + } else { + tloge("secfacedetect_reserve_tee_mem mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secfacedetect, "platform-secfacedetect", + secfacedetect_reserve_tee_mem); + +static u64 g_pt_addr = 0; +static u64 g_pt_size = 0; + +static int reserve_pt_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_pt_size = rmem->size; + g_pt_addr = rmem->base; + } else { + tloge("reserve pt mem is NULL\n"); + } + return 0; +} + +RESERVEDMEM_OF_DECLARE(pagetable, "platform-ai-pagetable", + reserve_pt_mem); + +static u64 g_pp_addr = 0; +static u64 g_pp_size = 0; + +static int reserve_pp_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_pp_addr = rmem->base; + g_pp_size = rmem->size; + } else { + tloge("reserve pp mem is NULL\n"); + } + return 0; +} + +RESERVEDMEM_OF_DECLARE(ai_running, "platform-ai-running", + reserve_pp_mem); + +static u64 g_voiceid_addr = 0; +static u64 g_voiceid_size = 0; +static int voiceid_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_voiceid_addr = rmem->base; + g_voiceid_size = rmem->size; + } else { + tloge("voiceid reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(voiceid, "platform-voiceid", + voiceid_reserve_tee_mem); + +static u64 g_secos_ex_addr; +static u64 g_secos_ex_size; +static int secos_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secos_ex_addr = rmem->base; + g_secos_ex_size = rmem->size; + } else { + tloge("secos reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secos_ex, "platform-secos-ex", + secos_reserve_tee_mem); + +static u64 g_ion_ex_mem_addr; +static u64 g_ion_ex_mem_size; +static int supersonic_ex_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) + { + g_ion_ex_mem_addr = rmem->base; + g_ion_ex_mem_size = rmem->size; + } else { + tloge("rmem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(supersonic_ex, "platform-supersonic-ex", + supersonic_ex_reserve_tee_mem); + +static void set_mem_tag(struct register_ion_mem_tag *memtag, + u64 addr, u64 size, uint32_t tag, uint32_t *pos) +{ + memtag->memaddr[*pos] = addr; + memtag->memsize[*pos] = size; + memtag->memtag[*pos] = tag; + (*pos)++; +} + +void set_ion_mem_info(struct register_ion_mem_tag *memtag) +{ + uint32_t pos = 0; + if(!memtag) { + tloge("invalid memtag\n"); + return; + } + + tlogi("ion mem static reserved for tee face=%d, finger=%d,voiceid=%d," + "secos=%d,finger-ex=%d, pt_size= %d,pp_size=%d\n", + (uint32_t)g_secfacedetect_mem_size, (uint32_t)g_ion_mem_size, + (uint32_t)g_voiceid_size, (uint32_t)g_secos_ex_size, + (uint32_t)g_ion_ex_mem_size, (uint32_t)g_pt_size, + (uint32_t)g_pp_size); + + if (g_ion_mem_addr != (u64)0 && g_ion_mem_size != (u64)0) + set_mem_tag(memtag,g_ion_mem_addr, g_ion_mem_size, PP_MEM_TAG, &pos); + if (g_secfacedetect_mem_addr != (u64)0 && g_secfacedetect_mem_size != (u64)0) + set_mem_tag(memtag,g_secfacedetect_mem_addr, g_secfacedetect_mem_size, PP_MEM_TAG, &pos); + if (g_voiceid_addr != (u64)0 && g_voiceid_size != (u64)0) + set_mem_tag(memtag, g_voiceid_addr, g_voiceid_size, PP_MEM_TAG, &pos); + if (g_secos_ex_addr != (u64)0 && g_secos_ex_size != (u64)0) + set_mem_tag(memtag, g_secos_ex_addr, g_secos_ex_size, PP_MEM_TAG, &pos); + if (g_pt_addr != (u64)0 && g_pt_size != (u64)0) + set_mem_tag(memtag, g_pt_addr, g_pt_size, PT_MEM_TAG, &pos); + if (g_pp_addr != (u64)0 && g_pp_size != (u64)0) + set_mem_tag(memtag, g_pp_addr, g_pp_size, PRI_PP_MEM_TAG, &pos); + if (g_ion_ex_mem_addr != (u64)0 && g_ion_ex_mem_size != (u64)0) + set_mem_tag(memtag, g_ion_ex_mem_addr, g_ion_ex_mem_size, PP_MEM_TAG, &pos); + /* here pos max is 7, memaddr[] has 10 positions, just 3 free */ + memtag->size = pos; + return; +} \ No newline at end of file diff --git a/tzdriver1/ion/mplat/declare_static_ion.c b/tzdriver1/ion/mplat/declare_static_ion.c new file mode 100644 index 0000000000000000000000000000000000000000..848ed11587bdad1462e6c0a87279885b01623180 --- /dev/null +++ b/tzdriver1/ion/mplat/declare_static_ion.c @@ -0,0 +1,39 @@ +#include "declare_static_ion.h" +#include +#include +#include "tc_ns_log.h" + +static u64 g_secos_ex_addr; +static u64 g_secos_ex_size; +static int secos_reserve_tee_mem(const struct reserved_mem *rmem) +{ + if (rmem) { + g_secos_ex_addr = rmem->base; + g_secos_ex_size = rmem->size; + } else { + tloge("secos reserve tee mem is NULL\n"); + } + return 0; +} +RESERVEDMEM_OF_DECLARE(secos_ex, "mediatek,tee_os_reserved_memory", + secos_reserve_tee_mem); + +void set_ion_mem_info(struct register_ion_mem_tag *memtag) +{ + uint32_t pos = 0; + if(!memtag) { + tloge("invalid memtag\n"); + return; + } + + tlogi("ion mem static reserved for tee secos=0x%x\n", (uint32_t)g_secos_ex_size); + + if (g_secos_ex_addr != (u64)0 && g_secos_ex_size != (u64)0) { + memtag->memaddr[pos] = g_secos_ex_addr; + memtag->memsize[pos] = g_secos_ex_size; + memtag->memtag[pos] = PP_MEM_TAG; + pos++; + } + memtag->size = pos; + return; +} \ No newline at end of file diff --git a/tzdriver1/ion/static_ion_mem.c b/tzdriver1/ion/static_ion_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..32db334d02ccccb974199313b2f283d1ba963bd8 --- /dev/null +++ b/tzdriver1/ion/static_ion_mem.c @@ -0,0 +1,58 @@ +#include "static_ion_mem.h" +#include +#include +#include +#include +#include +#ifdef DEF_ENG +#include +#include +#endif +#include "smc_smp.h" +#include "teek_ns_client.h" +#include "mailbox_mempool.h" +#include "tc_ns_log.h" +#include "declare_static_ion.h" + +/* send the ion static memory to tee */ +int tc_ns_register_ion_mem(void) +{ + struct tc_ns_smc_cmd smc_cmd = {{0}, 0}; + int ret = 0; + struct mb_cmd_pack *mb_pack = NULL; + struct register_ion_mem_tag *memtag = NULL; + + mb_pack = mailbox_alloc_cmd_pack(); + if (!mb_pack) { + tloge("mailbox alloc failed\n"); + return -ENOMEM; + } + memtag = mailbox_alloc(sizeof(*memtag), 0); + if (!memtag) { + mailbox_free(mb_pack); + return -ENOMEM; + } + set_ion_mem_info(memtag); + smc_cmd.cmd_type = CMD_TYPE_GLOBAL; + smc_cmd.cmd_id = GLOBAL_CMD_ID_REGISTER_ION_MEM; + + mb_pack->operation.paramtypes = TEE_PARAM_TYPE_MEMREF_INPUT; + mb_pack->operation.params[0].memref.buffer = + mailbox_virt_to_phys((uintptr_t)(void *)memtag); + mb_pack->operation.buffer_h_addr[0] = + (uint64_t)mailbox_virt_to_phys((uintptr_t)(void *)memtag) >> ADDR_TRANS_NUM; + mb_pack->operation.params[0].memref.size = sizeof(*memtag); + + smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); + smc_cmd.operation_h_phys = + (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM; + + if (tc_ns_smc(&smc_cmd)) { + ret = -EPERM; + tloge("send ion mem info failed\n"); + } + mailbox_free(mb_pack); + mailbox_free(memtag); + + return ret; +} \ No newline at end of file diff --git a/tzdriver1/ion/static_ion_mem.h b/tzdriver1/ion/static_ion_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..93304684532912629bd6980a975b9a50c8f24f2c --- /dev/null +++ b/tzdriver1/ion/static_ion_mem.h @@ -0,0 +1,31 @@ +#ifndef STATIC_ION_MEM_H +#define STATIC_ION_MEM_H +#include + +#define ION_MEM_MAX_SIZE 10 + +struct register_ion_mem_tag { + uint32_t size; + uint64_t memaddr[ION_MEM_MAX_SIZE]; + uint32_t memsize[ION_MEM_MAX_SIZE]; + uint32_t memtag[ION_MEM_MAX_SIZE]; +}; + +enum static_mem_tag { + MEM_TAG_MIN = 0, + PP_MEM_TAG = 1, + PRI_PP_MEM_TAG = 2, + PT_MEM_TAG = 3, + MEM_TAG_MAX, +}; + +#ifdef CONFIG_STATIC_ION +int tc_ns_register_ion_mem(void); +#else +static inline int tc_ns_register_ion_mem(void) +{ + return 0; +} +#endif + +#endif \ No newline at end of file diff --git a/tzdriver1/whitelist/Makefile b/tzdriver1/whitelist/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..db60e05d8a4a83ef44887ed09532c84269df8f99 --- /dev/null +++ b/tzdriver1/whitelist/Makefile @@ -0,0 +1,13 @@ +KERNEL_DIR := $(srctree) + +ifneq ($(TARGET_BUILD_VARIANT), user) + ccflags-y += -DDEF_ENG +endif + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/include +EXTRA_CFLAGS += -include internal_functions.h + +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver +EXTRA_CFLAGS += -I$(KERNEL_DIR)/drivers/platform_drivers/tzdriver/core + +obj-y += agent_allowed_ca.o \ No newline at end of file diff --git a/tzdriver1/whitelist/agent_allowed_ca.c b/tzdriver1/whitelist/agent_allowed_ca.c new file mode 100644 index 0000000000000000000000000000000000000000..1c5d3c050e8d31be71797fc85cf098ce6d414491 --- /dev/null +++ b/tzdriver1/whitelist/agent_allowed_ca.c @@ -0,0 +1,67 @@ +#include "agent.h" +#include +#include +#include + +static struct ca_info g_allowed_ext_agent_ca[] = { +#ifdef CONFIG_TZDRIVER + { + "/vendor/bin/hiaiserver", + 3094, + TEE_SECE_AGENT_ID, + }, + { + "/vendor/bin/hw/vendor.huawei.hardware.\ + biometrics.hwfacerecognize@1.1-service", + 1000, + TEE_FACE_AGENT1_ID, + }, + { + "/vendor/bin/hw/vendor.huawei.hardware.\ + biometrics.hwfacerecognize@1.1-service", + 1000, + TEE_FACE_AGENT2_ID, + }, +#endif +#ifdef DEF_ENG + { + "/vendor/bin/tee_test_agent", + 0, + TEE_SECE_AGENT_ID, + }, +#endif +}; + +int is_allowed_agent_ca(const struct ca_info *ca, + bool check_agent_id) +{ + uint32_t i; + struct ca_info *tmp_ca = g_allowed_ext_agent_ca; + const uint32_t nr = ARRAY_SIZE(g_allowed_ext_agent_ca); + + if (!ca) + return -EFAULT; + + if (!check_agent_id) { + for (i = 0; i < nr; i++) { + if (!strncmp(ca->path, tmp_ca->path, + strlen(tmp_ca->path) + 1) && + ca->uid == tmp_ca->uid) + return 0; + tmp_ca++; + } + } else { + for (i = 0; i < nr; i++) { + if (!strncmp(ca->path, tmp_ca->path, + strlen(tmp_ca->path) + 1) && + ca->uid == tmp_ca->uid && + ca->agent_id == tmp_ca->agent_id) + return 0; + tmp_ca++; + } + } + tlogd("ca-uid is %u, ca_path is %s, agent id is %x\n", ca->uid, + ca->path, ca->agent_id); + + return -EACCES; +} \ No newline at end of file