From 15adfe872ee62a6acdc4a85bbe6805f4f20059ed Mon Sep 17 00:00:00 2001 From: lilianhui <10873511+lilianhui@user.noreply.gitee.com> Date: Wed, 4 May 2022 10:34:59 +0000 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=9C=80=E6=B1=82=E4=BB=B7=E5=80=BC?= =?UTF-8?q?=E3=80=91=20=E6=8F=90=E4=BE=9B=E9=9B=B6=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E5=86=85=E5=AD=98=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E5=86=85=E5=AD=98=E8=AE=BF=E9=97=AE=E6=95=88?= =?UTF-8?q?=E7=8E=87=20=E3=80=90=E9=9C=80=E6=B1=82=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E3=80=91=20CA=E7=94=B3=E8=AF=B7=E9=9D=9E=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E5=86=85=E5=AD=98=E4=BD=9C=E4=B8=BA=E5=85=B1=E4=BA=AB=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=98=A0=E5=B0=84=E7=BB=99TA=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=9B=B6=E6=8B=B7=E8=B4=9D=E5=85=B1=E4=BA=AB=E5=86=85?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- Makefile | 2 +- core/gp_ops.c | 152 ++++++++++++++++++++++++++++++++++++++++ core/gp_ops.h | 7 ++ tc_ns_client.h | 4 ++ teek_client_constants.h | 2 + teek_ns_client.h | 4 ++ 7 files changed, 171 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd58879..cf887c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(KERNEL_DIR ${KPATH}/${KDIR}) set(CMAKE_EXTRA_FLAGS "-fstack-protector-strong -DCONFIG_TEELOG -DCONFIG_TZDRIVER_MODULE -DCONFIG_TEECD_AUTH -DCONFIG_PAGES_MEM=y -DCONFIG_AUTH_ENHANCE -DCONFIG_CLOUDSERVER_TEECD_AUTH") set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -DCONFIG_CPU_AFF_NR=0 -DCONFIG_BIG_SESSION=1000 -DCONFIG_NOTIFY_PAGE_ORDER=4 -DCONFIG_512K_LOG_PAGES_MEM") set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -DCONFIG_TEE_LOG_ACHIVE_PATH=\\\\\\\"/var/log/tee/last_teemsg\\\\\\\"") -set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -DNOT_TRIGGER_AP_RESET -DLAST_TEE_MSG_ROOT_GID") +set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -DNOT_TRIGGER_AP_RESET -DLAST_TEE_MSG_ROOT_GID -DCONFIG_NOCOPY_SHAREDMEM") set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -I${PROJECT_SOURCE_DIR}/libboundscheck/include/ -I${PROJECT_SOURCE_DIR} -I${PROJECT_SOURCE_DIR}/auth -I${PROJECT_SOURCE_DIR}/core") set(CMAKE_EXTRA_FLAGS "${CMAKE_EXTRA_FLAGS} -I${PROJECT_SOURCE_DIR}/tlogger -I${PROJECT_SOURCE_DIR}/kthread_affinity") diff --git a/Makefile b/Makefile index 253938d..09f2fea 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ EXTRA_CFLAGS += -I$(PWD)/libboundscheck/include/ -I$(PWD) -I$(PWD)/auth -I$(PWD) EXTRA_CFLAGS += -I$(PWD)/tlogger -I$(PWD)/kthread_affinity EXTRA_CFLAGS += -DCONFIG_CPU_AFF_NR=0 -DCONFIG_BIG_SESSION=1000 -DCONFIG_NOTIFY_PAGE_ORDER=4 -DCONFIG_512K_LOG_PAGES_MEM EXTRA_CFLAGS += -DCONFIG_TEE_LOG_ACHIVE_PATH=\"/var/log/tee/last_teemsg\" -EXTRA_CFLAGS += -DNOT_TRIGGER_AP_RESET -DLAST_TEE_MSG_ROOT_GID +EXTRA_CFLAGS += -DNOT_TRIGGER_AP_RESET -DLAST_TEE_MSG_ROOT_GID -DCONFIG_NOCOPY_SHAREDMEM all: make -C $(KDIR) M=$(PWD) modules clean: diff --git a/core/gp_ops.c b/core/gp_ops.c index f73aca0..5d71256 100644 --- a/core/gp_ops.c +++ b/core/gp_ops.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include #include "teek_client_constants.h" @@ -531,6 +534,125 @@ static int alloc_for_ref_mem(const struct tc_call_params *call_params, return ret; } +#ifdef CONFIG_NOCOPY_SHAREDMEM +static int fill_sharedmem_info(void *start_vaddr, uint32_t pages_no, + uint32_t offset, uint32_t buffer_size, void *buff) +{ + struct pagelist_info *page_info = NULL; + struct page **pages = NULL; + uint64_t *phys_addr = NULL; + uint32_t page_num; + uint32_t i; + + if (pages_no == 0) + return -EFAULT; + + page = (struct page **)vmalloc(pages_no * sizeof(uint64_t)); + if (page == NULL) + return -EFAULT; + + down_read(&(current->mm->mmap_sem)); + page_num = get_user_pages(start_vaddr, pages_no, 0, pages, NULL); + up_read(&(current->mm->mmap_sem)); + if (pages_num != pages_no) { + tloge("get page phy addr failed\n"); + if (page_num > 0) + relase_pages(pages, page_num); + vfree(pages); + return -EFAULT; + } + + page_info = buff; + page_info->page_num = pages_no; + page_info->page_size = PAGE_SIZE; + page_info->sharedmem_offset = offset; + page_info->sharedmem_szie = buffer_size; + + phys_addr = (uint64_t *)buff + (sizeof(*page_info) / sizeof(uint64_t)); + for (i = 0; i < pages_no; i++) { + struct page *page = pages[i]; + if (page == NULL) { + relase_pages(pages, page_num); + vfree(pages); + return -EFAULT; + } + phys_addr[i] = (uintptr_t)page_to_phys(page); + } + + vfree(pages); + return 0; +} + +static int check_buffer_for_sharedmem(uint32_t *buffer_size, + const union tc_ns_client_param *client_param, uint8_t kernel_params) +{ + if (read_from_client(buffer_size, sizeof(*buffer_size), + (uint32_t __user *)(uintptr_t)client_param->sharedmem.size_addr, + sizeof(uint32_t), kernel_params)) { + tloge("copy sharedmem.size_addr failed\n"); + return -EFAULT; + } + + if (*buffer_size == 0 || *buffer_size > SZ_256M) { + tloge("buffer_size from user is 0\n"); + return -ENOMEM; + } + + return 0; +} + +static int transfer_shared_mem(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 *buff = NULL; + void *start_vaddr = NULL; + union tc_ns_client_param *client_param = NULL; + uint32_t buffer_size; + uint32_t pages_no; + uint32_t offset; + uint32_t buff_len; + + if (index >= TEE_PARAM_NUM) + return -EFAULT; + + client_param = &(call_params->context->param[index]); + if (check_buffer_for_sharedmem(&buffer_size, client_param, kernel_params)) + return -EFAULT; + + buff = (void *)(uint64_t)client_param->sharedmem.buffer; + start_vaddr = (void *)(((uint64_t)buff) & PAGE_MASK); + offset = ((uint32_t)(uintptr_t)buff) & (~PAGE_MASK); + pages_no = PAGE_ALIGN(offset + buffer_size) / PAGE_SIZE; + + buff_len = sizeof(struct pagelist_info) + (sizeof(uint64_t) * pages_no); + buff = mailbox_alloc(buff_len, MB_FLAG_ZERO); + if (buff == NULL) + return -EFAULT; + if(fill_sharedmem_info(start_vaddr, pages_no, offset, buffer_size, buff)) { + mailbox_free(buff); + return -EFAULT; + } + + op_params->local_tmpbuf[index].temp_buffer = buff; + op_params->local_tmpbuf[index].size = buff_len; + + op_params->mb_pack->operation.param[index].shared_mem.buffer = virt_to_phys(buff); + op_params->mb_pack->operation.buffer_h_addr = (uint64_t)virt_to_phys(buff) >> ADDR_TRANS_NUM; + op_params->mb_pack->operation.param[index].shared_mem.size = buff_len; + op_params->trans_paramtype[index] = param_type; + return 0; +} +#else +static int transfer_shared_mem(const struct tc_call_params *call_params, + struct tc_op_params *op_params, uint8_t kernel_params, + uint32_t param_type, unsigned int index) +{ + tloge("invalid shared mem type\n"); + return -1; +} +#endif + static int transfer_client_value(const struct tc_call_params *call_params, struct tc_op_params *op_params, uint8_t kernel_params, uint32_t param_type, unsigned int index) @@ -619,6 +741,9 @@ static int alloc_operation(const struct tc_call_params *call_params, else if (param_type == TEEC_ION_SGLIST_INPUT) ret = alloc_for_ion_sglist(call_params, op_params, kernel_params, param_type, index); + else if (param_type == TEEC_MEMREF_SHARED_INOUT) + ret = transfer_shared_mem(call_params, op_params, + kernel_params, param_type, index); else tlogd("param type = TEEC_NONE\n"); @@ -797,6 +922,25 @@ static int update_client_operation(const struct tc_call_params *call_params, return ret; } +#if CONFIG_NOCOPY_SHAREDMEM +static void relase_page(void *buf) +{ + uint32_t i; + uint64_t *phys_addr = NULL; + struct pagelist_info *page_info = NULL; + struct page *page = NULL; + + page_info = buf; + phys_addr = (uint64_t *)buf + (sizeof(*page_info) / sizeof(uint64_t)); + for (i = 0; i < page_info->page_num; i++) { + page = (uintptr_t)phys_to_page(phys_addr[i]); + if (page == NULL) + continue; + put_page(page); + } +} +#endif + static void free_operation(const struct tc_call_params *call_params, struct tc_op_params *op_params) { @@ -833,6 +977,14 @@ static void free_operation(const struct tc_call_params *call_params, mailbox_free(temp_buf); temp_buf = NULL; } + } else if (param_type == TEEC_MEMREF_SHARED_INOUT) { +#if CONFIG_NOCOPY_SHAREDMEM + temp_buf = local_tmpbuf[index].temp_buffer; + if (temp_buf != NULL) { + relase_page(temp_buf); + mailbox_free(temp_buf); + } +#endif } } } diff --git a/core/gp_ops.h b/core/gp_ops.h index 9a19269..c730e7b 100644 --- a/core/gp_ops.h +++ b/core/gp_ops.h @@ -35,6 +35,13 @@ struct tc_op_params { bool op_inited; }; +struct pagelist_info { + uint64_t page_num; + uint64_t page_size; + uint64_t sharedmem_offset; + uint64_t sharedmem_size; +}; + int write_to_client(void __user *dest, size_t dest_size, const void *src, size_t size, uint8_t kernel_api); int read_from_client(void *dest, size_t dest_size, diff --git a/tc_ns_client.h b/tc_ns_client.h index 814a578..ea83e7a 100644 --- a/tc_ns_client.h +++ b/tc_ns_client.h @@ -51,6 +51,10 @@ union tc_ns_client_param { __u64 a_addr; __u64 b_addr; } value; + struct { + __u64 buffer; + __u64 size_addr; + } sharedmem; }; struct tc_ns_client_return { diff --git a/teek_client_constants.h b/teek_client_constants.h index 6e48e22..cecf27c 100644 --- a/teek_client_constants.h +++ b/teek_client_constants.h @@ -131,6 +131,7 @@ enum TEEC_ParamType { TEEC_MEMREF_TEMP_INOUT = 0x07, TEEC_ION_INPUT = 0x08, TEEC_ION_SGLIST_INPUT = 0x09, + TEEC_MEMREF_SHARED_INOUT = 0xa, TEEC_MEMREF_WHOLE = 0xc, TEEC_MEMREF_PARTIAL_INPUT = 0xd, TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, @@ -147,6 +148,7 @@ enum TEE_ParamType { TEE_PARAM_TYPE_MEMREF_INOUT = 0x7, TEE_PARAM_TYPE_ION_INPUT = 0x8, TEE_PARAM_TYPE_ION_SGLIST_INPUT = 0x9, + TEE_PARAM_TYPE_MEMREF_SHARED_INOUT = 0xa, }; enum TEEC_LoginMethod { diff --git a/teek_ns_client.h b/teek_ns_client.h index b9271e8..6cd6a3a 100644 --- a/teek_ns_client.h +++ b/teek_ns_client.h @@ -116,6 +116,10 @@ union tc_ns_parameter { unsigned int a; unsigned int b; } value; + struct { + unsigned int buffer; + unsigned int size; + } sharedmem; }; struct tc_ns_login { -- Gitee