From b5190355e2b6d40e89f603aa4b9b67b23cc4a29f Mon Sep 17 00:00:00 2001 From: whrisky Date: Mon, 3 Jul 2023 09:54:31 +0800 Subject: [PATCH] sync tzdriver --- core/mailbox_mempool.c | 417 +++++++++++++++++++++++++++-------------- core/mailbox_mempool.h | 5 + core/session_manager.c | 134 ++++++++++--- core/session_manager.h | 2 +- core/shared_mem.h | 14 ++ core/tz_spi_notify.c | 12 +- core/tz_spi_notify.h | 1 - 7 files changed, 408 insertions(+), 177 deletions(-) diff --git a/core/mailbox_mempool.c b/core/mailbox_mempool.c index e088e59..4fdaced 100644 --- a/core/mailbox_mempool.c +++ b/core/mailbox_mempool.c @@ -43,6 +43,11 @@ static int g_max_oder; #define OPT_MODE 0660U #define STATE_MODE 0440U +#ifndef MAILBOX_POOL_COUNT +#define MAILBOX_POOL_COUNT 1 +#endif +#define MAILBOX_POOL_MAX 32 + struct mb_page_t { struct list_head node; mailbox_page_t *page; @@ -61,35 +66,60 @@ struct mb_zone_t { struct mb_free_area_t free_areas[0]; }; -static struct mb_zone_t *g_m_zone; +static struct mb_zone_t **g_m_zone; +static uint32_t g_mb_count; static struct mutex g_mb_lock; +static bool check_zone(void) +{ + if (g_m_zone == NULL) + return false; + for ( i = 0; i < g_mb_count; i++) + { + if (g_m_zone[i] == NULL) + return false; + } + return true; + +} + static void mailbox_show_status(void) { - unsigned int i; + unsigned int i, j; struct mb_page_t *pos = NULL; struct list_head *head = NULL; unsigned int used = 0; - if (!g_m_zone) { + tloge("########################################\n"); + mutex_lock(&g_mb_lock); + if (check_zone() == false) { tloge("zone struct is NULL\n"); + mutex_unlock(&g_mb_lock); return; } - tloge("########################################\n"); - mutex_lock(&g_mb_lock); - for (i = 0; i < MAILBOX_PAGE_MAX; i++) { - if (g_m_zone->pages[i].count != 0) { - tloge("page[%02d], order=%02d, count=%d\n", - i, g_m_zone->pages[i].order, - g_m_zone->pages[i].count); - used += (1 << (uint32_t)g_m_zone->pages[i].order); + for ( i = 0; i < g_mb_count; i++) { + for (j = 0; j < MAILBOX_POOL_MAX; j++) { + if (g_m_zone[i]->pages[j].count != 0) { + tloge("zone[%03d], page[%02d], order=%02d, count=%d\n", + i, j, g_m_zone[i]->pages[j].order, g_m_zone[i]->pages[j].count); + } } } - tloge("total usage:%u/%u\n", used, MAILBOX_PAGE_MAX); + + tloge("total usage:%u/%u\n", used, *g_mb_count); tloge("----------------------------------------\n"); for (i = 0; i < (unsigned int)g_max_oder; i++) { + for (j = 0; j < g_max_oder; j++) { + head = &g_m_zone[i]->free_areas[j].page_list; + if (list_empty(head) != 0) { + tloge("zone[%03d], order[%02d] is not empty"); + } else { + list_for_each_entry(pos, head, node) + tloge("zone[%03d], order[%02d]\n", i, j); + } + } head = &g_m_zone->free_areas[i].page_list; if (list_empty(head) != 0) { tloge("order[%02d] is empty\n", i); @@ -107,28 +137,31 @@ static void mailbox_show_status(void) #define BITS_OF_BYTE 8 static void mailbox_show_details(void) { - unsigned int i; + unsigned int i, j; unsigned int used = 0; unsigned int left = 0; unsigned int order = 0; - if (!g_m_zone) { + tloge("----- show mailbox details -----"); + mutex_lock(&g_mb_lock); + + if (check_zone()) { tloge("zone struct is NULL\n"); + mutex_unlock(&g_mb_lock); return; } - tloge("----- show mailbox details -----"); - mutex_lock(&g_mb_lock); - for (i = 0; i < MAILBOX_PAGE_MAX; i++) { - if (i % MB_SHOW_LINE == 0) { - tloge("\n"); - tloge("%04d-%04d:", i, i + MB_SHOW_LINE); - } - - if (g_m_zone->pages[i].count != 0) { - left = 1 << (uint32_t)g_m_zone->pages[i].order; - order = (uint32_t)g_m_zone->pages[i].order; - used += (1 << (uint32_t)g_m_zone->pages[i].order); + for (i = 0; i < g_mb_count; i++) { + for (j = 0; j < MAILBOX_PAGE_MAX; j++) { + if(j % MB_SHOW_LINE == 0) { + tloge("\n"); + tloge("%04d-%04d:", j, j + MB_SHOW_LINE); + } + if (g_m_zone[j]->page[j].count != 0) { + left = 1 << (uint32_t)g_m_zone[i]->pages[j].order; + order = (uint32_t)g_m_zone[i]->pages[j].order; + used += (1 << (uint32_t)g_m_zone[i]->pages[j].order); + } } if (left != 0) { @@ -138,25 +171,21 @@ static void mailbox_show_details(void) tloge("X"); } - if (i > 1 && (i + 1) % (MB_SHOW_LINE / BITS_OF_BYTE) == 0) + if (j > 1 && (j + 1) % (MB_SHOW_LINE / BITS_OF_BYTE) == 0) tloge(" "); } - tloge("total usage:%u/%u\n", used, MAILBOX_PAGE_MAX); + tloge("total usage:%u/%u\n", used, *g_mb_count); mutex_unlock(&g_mb_lock); } void *mailbox_alloc(size_t size, unsigned int flag) { - unsigned int i; + unsigned int i, j, k; struct mb_page_t *pos = (struct mb_page_t *)NULL; struct list_head *head = NULL; int order = get_order(ALIGN(size, SZ_4K)); void *addr = NULL; - - if ((size == 0) || !g_m_zone) { - tlogw("alloc 0 size mailbox or zone struct is NULL\n"); - return NULL; - } + bool tag = false if (order > g_max_oder || order < 0) { tloge("invalid order %d\n", order); @@ -164,37 +193,47 @@ void *mailbox_alloc(size_t size, unsigned int flag) } mutex_lock(&g_mb_lock); - for (i = (unsigned int)order; i <= (unsigned int)g_max_oder; i++) { - unsigned int j; - head = &g_m_zone->free_areas[i].page_list; - if (list_empty(head) != 0) - continue; + if ((size == 0) || !check_zone()) { + tlogw("alloc 0 size mailbox or zone struct is NULL\n"); + mutex_unlock(&g_mb_lock); + return NULL; + } + + for(k = 0; k < g_mb_count; k++) { + for (i = (unsigned int)order; i <= (unsigned int)g_max_oder; i++) { + unsigned int j; + + head = &g_m_zone[k]->free_areas[i].page_list; + if (list_empty(head) != 0) + continue; - pos = list_first_entry(head, struct mb_page_t, node); + pos = list_first_entry(head, struct mb_page_t, node); - pos->count = 1; - pos->order = order; + pos->count = 1; + pos->order = order; - /* split and add free list */ - for (j = (unsigned int)order; j < i; j++) { - struct mb_page_t *new_page = NULL; + /* split and add free list */ + for (j = (unsigned int)order; j < i; j++) { + struct mb_page_t *new_page = NULL; - new_page = pos + (1 << j); - new_page->count = 0; - new_page->order = (int)j; - list_add_tail(&new_page->node, - &g_m_zone->free_areas[j].page_list); + new_page = pos + (1 << j); + new_page->count = 0; + new_page->order = (int)j; + list_add_tail(&new_page->node, + &g_m_zone[k]->free_areas[j].page_list); + } + list_del(&pos->node); + addr = (void *)mailbox_page_address(pos->page); + tag = true; + break; } - list_del(&pos->node); - addr = (void *)mailbox_page_address(pos->page); - break; } + mutex_unlock(&g_mb_lock); if (addr && ((flag & MB_FLAG_ZERO) != 0)) { - if (memset_s(addr, ALIGN(size, SZ_4K), - 0, ALIGN(size, SZ_4K)) != 0) { + if (memset_s(addr, ALIGN(size, SZ_4K), 0, ALIGN(size, SZ_4K)) != 0) { tloge("clean mailbox failed\n"); mailbox_free(addr); return NULL; @@ -203,34 +242,35 @@ void *mailbox_alloc(size_t size, unsigned int flag) return addr; } -static void add_max_order_block(unsigned int idex) +static void add_max_order_block(unsigned int order, unsigned int index) { struct mb_page_t *self = NULL; - if (idex != (unsigned int)g_max_oder || !g_m_zone) + if (order != (unsigned int)g_max_oder || !g_m_zone) return; /* - * when idex equal max order, no one use mailbox mem, + * when order equal max order, no one use mailbox mem, * we need to hang all pages in the last free area page list */ - self = &g_m_zone->pages[0]; + self = &g_m_zone[index]->pages[0]; list_add_tail(&self->node, - &g_m_zone->free_areas[g_max_oder].page_list); + &g_m_zone[index]->free_areas[g_max_oder].page_list); } -static bool is_ptr_valid(const mailbox_page_t *page) +static bool is_ptr_valid(const mailbox_page_t *page, unsigned int *index) { - if (!g_m_zone) - return false; - - if (page < g_m_zone->all_pages || - page >= (g_m_zone->all_pages + MAILBOX_PAGE_MAX)) { - tloge("invalid ptr to free in mailbox\n"); - return false; + unsigned int i; + for (i = 0; i < g_mb_count; i++) { + if (page >= g_m_zone[i]->all_pages && + page < (g_m_zone[i]->all_pages + MAILBOX_PAGE_MAX)) { + *index = i; + return true; + } } - return true; + tloge("invaild ptr to free in mailbox\n"); + return false; } void mailbox_free(const void *ptr) @@ -241,31 +281,32 @@ void mailbox_free(const void *ptr) struct mb_page_t *buddy = NULL; unsigned int self_idx; unsigned int buddy_idx; + unsigned int index = 0; - if (!ptr || !g_m_zone) { - tloge("invalid ptr\n"); - return; + mutex_lock(&g_mb_lock); + if (!ptr || !check_zone()) { + tloge("invalid ptr or zone struct is NULL\n"); + goto end; } page = mailbox_virt_to_page((uint64_t)(uintptr_t)ptr); - if (!is_ptr_valid(page)) - return; + if (!is_ptr_valid(page, index)) + goto end; mutex_lock(&g_mb_lock); - self_idx = page - g_m_zone->all_pages; - self = &g_m_zone->pages[self_idx]; + self_idx = page - g_m_zone[index]->all_pages; + self = &g_m_zone[index]->pages[self_idx]; if (self->count == 0) { tloge("already freed in mailbox\n"); - mutex_unlock(&g_mb_lock); - return; + goto end; } for (i = (unsigned int)self->order; i < (unsigned int)g_max_oder; i++) { - self_idx = page - g_m_zone->all_pages; + self_idx = page - g_m_zone[index]->all_pages; buddy_idx = self_idx ^ (uint32_t)(1 << i); - self = &g_m_zone->pages[self_idx]; - buddy = &g_m_zone->pages[buddy_idx]; + self = &g_m_zone[index]->pages[self_idx]; + buddy = &g_m_zone[index]->pages[buddy_idx]; self->count = 0; /* is buddy free */ if ((unsigned int)buddy->order == i && buddy->count == 0) { @@ -283,13 +324,13 @@ void mailbox_free(const void *ptr) } else { /* release self */ list_add_tail(&self->node, - &g_m_zone->free_areas[i].page_list); - mutex_unlock(&g_mb_lock); - return; + &g_m_zone[index]->free_areas[i].page_list); + goto end; } } - add_max_order_block(i); + add_max_order_block(i, index); +end: mutex_unlock(&g_mb_lock); } @@ -535,7 +576,7 @@ static int mailbox_register(const void *mb_pool, unsigned int size) } operation->paramtypes = TEE_PARAM_TYPE_VALUE_INPUT | - (TEE_PARAM_TYPE_VALUE_INPUT << TEE_PARAM_NUM); + (TEE_PARAM_TYPE_VALUE_INOUT << TEE_PARAM_NUM); operation->params[0].value.a = mailbox_virt_to_phys((uintptr_t)mb_pool); operation->params[0].value.b = (uint64_t)mailbox_virt_to_phys((uintptr_t)mb_pool) >> ADDR_TRANS_NUM; @@ -548,14 +589,19 @@ static int mailbox_register(const void *mb_pool, unsigned int size) (uint64_t)mailbox_virt_to_phys((uintptr_t)operation) >> ADDR_TRANS_NUM; if (is_tee_rebooting()) - ret = send_smc_cmd_rebooting(TSP_REQUEST, 0, 0, smc_cmd); + ret = send_smc_cmd_rebooting(TSP_REQUEST, smc_cmd); else ret= tc_ns_smc(smc_cmd); if (ret != 0) { tloge("resigter mailbox failed\n"); ret = -EIO; + } else { + if(operation->params->value.a <= g_mb_count || g_mb_count == 0) + g_mb_count = operation->params->value.a; + tlogi("wish to register %u mailbox, success %u\n", (unit32_t) MAILBOX_POOL_COUNT, g_mb_count); } + free_operation((uint64_t)(uintptr_t)operation); operation = NULL; @@ -571,87 +617,174 @@ static void mailbox_debug_init(void) int re_register_mailbox(void) { - if (!g_m_zone) + uint32_t i; + int ret = 0; + struct mailbox_buffer *buffer = NULL; + + mutex_lock(&g_mb_lock); + if (!check_zone()) { + mutex_unlock(&g_mb_lock); return -EFAULT; - if (g_m_zone->all_pages != NULL) { - if (memset_s((void *)mailbox_page_address(g_m_zone->all_pages), - MAILBOX_POOL_SIZE, 0, MAILBOX_POOL_SIZE) != EOK) { - tloge("memset mailbox failed\n"); - return -EFAULT; - } + } + + buffer = (struct mailbox_buffer *)get_mailbox_buffer_vaddr(g_mb_count); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) { + mutex_unlock(&g_mb_lock); + return -ENOMEM; + } + for (i = 0; i < g_mb_count; i++) { + (void)memset_s((void *)mailbox_page_address(g_m_zone[i]->all_pages), + MAILBOX_POOL_SIZE, 0, MAILBOX_POOL_SIZE); + buffer[i] = mailbox_virt_to_phys(mailbox_page_address(g_m_zone[i]->all_pages)); + buffer[i].size = MAILBOX_POOL_SIZE; - if (mailbox_register((const void *)mailbox_page_address(g_m_zone->all_pages), MAILBOX_POOL_SIZE) != 0) { - tloge("register mailbox failed\n"); - return -EIO; - } } - return 0; + mutex_unlock(&g_mb_lock); + + + if (mailbox_register(buffer, sizeof(struct mailbox_buffer) *g_mb_count)!= 0) { + tloge("register mailbox failed\n"); + return -EIO; + } + + free_mailbox_buffer((uint64_t)(uintptr_t)buffer); + return ret; } -int mailbox_mempool_init(void) +static int init_zone(struct mailbox_page_t **all_pages) { - int i; + uint32 i, j; struct mb_page_t *mb_page = NULL; struct mb_free_area_t *area = NULL; - mailbox_page_t *all_pages = NULL; - size_t zone_len; - g_max_oder = get_order(MAILBOX_POOL_SIZE); - tlogi("in this RE, mailbox max order is: %d\n", g_max_oder); + size_t zone_len; - /* zone len is fixed, will not overflow */ - zone_len = sizeof(*area) * (g_max_oder + 1) + sizeof(*g_m_zone); - g_m_zone = kzalloc(zone_len, GFP_KERNEL); + g_m_zone = kzalloc(sizeof(struct mb_zone_t **) *g_mb_count, GFP_KERNEL); if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)g_m_zone)) { - tloge("fail to alloc zone struct\n"); - return -ENOMEM; + tloge("alloc m_zone failed\n"); + return -ENOMEM; + } + + zone_len = sizeof(*area) * (g_max_oder + 1) + sizeof(struct mb_zone_t); + for (i = 0; i < g_mb_count; i++) { + g_m_zone[i] = kzalloc(zone_len, GFP_KERNEL); + if(ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)g_m_zone[i])) { + tloge("fail to alloc zone\n"); + goto clear; + } + for(j = 0; j < MAILBOX_PAGE_MAX; j++) { + g_m_zone[i]->page[j].order = -1; + g_m_zone[i]->page[j].count = 0; + g_m_zone[i]->page[j].page = &all_pages[i][j]; + } + g_m_zone[i]->page[0].order = g_max_oder; + + for(j = 0; j < MAILBOX_PAGE_MAX; j++) { + area = &g_m_zone[i]->free_areas[j]; + INIT_LIST_HEAD(&area->page_list); + area->order = j; + } + + mb_page = &g_m_zone[i]->page[0]; + list_add_tail(&mb_page->node, &area->page_list); + g_m_zone[i]->all_pages = all_pages[i]; } + return 0; +clear: + for(j = 0; j < i; j++) + kfree(g_m_zone[j]); + + kfree(g_m_zone); + return -ENOMEM; +} - all_pages = mailbox_alloc_pages(g_max_oder); - if (!all_pages) { - tloge("fail to alloc mailbox mempool\n"); - kfree(g_m_zone); - g_m_zone = NULL; - return -ENOMEM; +static int init_mailbox(uint32_t pool_count, mailbox_page_t **all_pages) +{ + uint32_t i; + int ret = 0; + struct mailbox_buffer *buffer = NULL; + + buffer = (struct mailbox_buffer *)(uintprt_t) get_mailbox_buffer_vaddr(pool_count); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)buffer)) + return -ENOMEM; + for (i = 0; i < pool_count; i++) { + buffer[i] = mailbox_virt_to_phys(mailbox_page_address(all_pages[i])); + buffer[i].size = MAILBOX_POOL_SIZE; } + if(mailbox_register(buffer, sizeof(mailbox_buffer) * pool_count) != 0) { + tloge("mailbox register failed\n"); + ret = -EIO; + goto clear; + } + mutex_lock(&g_mb_lock); + mailbox_debug_init(); +clear: + free_mailbox_buffer((uint64_t)(uintptr_t)buffer); + return ret; +} - if (mailbox_register((const void *)mailbox_page_address(all_pages), MAILBOX_POOL_SIZE) != 0) { - tloge("register mailbox failed\n"); - mailbox_free_pages(all_pages, g_max_oder); - kfree(g_m_zone); - g_m_zone = NULL; - return -EIO; +int mailbox_mempool_init(void) +{ + uint32_t pool_count, i; + mailbox_page_t **all_pages = NULL; + int ret = 0; + + if(MAILBOX_POOL_COUNT < 1 || MAILBOX_POOL_COUNT > MAILBOX_POOL_MAX) { + tloge("mailbox pool count invalid %d\n", MAILBOX_POOL_COUNT); + return -EINVAL; } - for (i = 0; i < MAILBOX_PAGE_MAX; i++) { - g_m_zone->pages[i].order = -1; - g_m_zone->pages[i].count = 0; - g_m_zone->pages[i].page = &all_pages[i]; + g_max_oder = get_order(MAILBOX_POOL_COUNT); + all_pages = kmalloc(sizeof(mailbox_page_t**) * g_max_oder, GFK_KERNEL); + if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)all_pages)) { + tloge("fail to alloc mailbox mempool\n"); + return -ENOMEM; + } + + for (pool_count = 0; pool_count < MAILBOX_POOL_COUNT; pool_count++) { + all_pages[pool_count] = mailbox_alloc_pages(a_max_oder); + if(!all_pages[pool_count]) { + tloge("fail to alloc pages\n"); + break; + } + } + if (pool_count == 0) { + ret = -ENOMEM; + goto clear_pages; } - g_m_zone->pages[0].order = g_max_oder; + ret = init_mailbox(pool_count, all_pages); + if(ret != 0) { + tloge("mailbox init failed\n"); + goto clear_mailbox; + } - for (i = 0; i <= g_max_oder; i++) { - area = &g_m_zone->free_areas[i]; - INIT_LIST_HEAD(&area->page_list); - area->order = i; + for(i = g_mb_count; i < pool_count; i++) { + mailbox_free_pages(all_pages[i], g_max_oder); + all_pages[i] = NULL; } - mb_page = &g_m_zone->pages[0]; - list_add_tail(&mb_page->node, &area->page_list); - g_m_zone->all_pages = all_pages; - mutex_init(&g_mb_lock); - mailbox_debug_init(); - return 0; + return ret; +clear_mailbox: + for (i = 0; i < pool_count; i++) { + mailbox_free_pages(all_pages[i], g_max_oder); + all_pages[i] = NULL; + } + +clear_pages: + kfree(all_pages); + return ret; } void free_mailbox_mempool(void) { - mailbox_free_pages(g_m_zone->all_pages, g_max_oder); - g_m_zone->all_pages = NULL; - kfree(g_m_zone); - g_m_zone = NULL; - + unsigned int i; + for (i = 0; i < g_mb_count; i++) { + mailbox_free_pages(g_m_zone[i]->all_pages, g_max_oder); + g_m_zone[i]->all_pages = NULL; + kfree(g_m_zone[i]); + g_m_zone[i] = NULL; + } if (!g_mb_dbg_dentry) return; debugfs_remove_recursive(g_mb_dbg_dentry); diff --git a/core/mailbox_mempool.h b/core/mailbox_mempool.h index b27ad42..5524e30 100644 --- a/core/mailbox_mempool.h +++ b/core/mailbox_mempool.h @@ -30,6 +30,11 @@ #define MB_FLAG_ZERO 0x1 /* set 0 after alloc page */ #define GLOBAL_UUID_LEN 17 /* first char represent global cmd */ +struct mailbox_buffer { + uint64_t buffer; + uint32_t size; +}; + void *mailbox_alloc(size_t size, unsigned int flag); void mailbox_free(const void *ptr); int mailbox_mempool_init(void); diff --git a/core/session_manager.c b/core/session_manager.c index 48e21c5..7de96ad 100644 --- a/core/session_manager.c +++ b/core/session_manager.c @@ -41,6 +41,9 @@ #include #endif #include +#ifndef CONFI_CONFIDENT_CONTAINER +#include +#endif #include #include "smc_smp.h" #include "mem.h" @@ -60,6 +63,22 @@ static DEFINE_MUTEX(g_load_app_lock); struct list_head g_service_list; DEFINE_MUTEX(g_service_list_lock); +static int lock_interruptible(struct mutex *lock) +{ + int ret; + + do { + ret = mutex_lock_interruptible(lock); + if (ret != 0) { + if(sigkill_pending(current)) + return ret; + tloge("signal try relock ret %d", ret); + continue; + } + } while (0); + return 0; +} + void init_srvc_list(void) { INIT_LIST_HEAD(&g_service_list); @@ -257,8 +276,8 @@ struct tc_ns_session *tc_find_session_by_uuid(unsigned int dev_file_id, return session; } -static int tc_ns_need_load_image(unsigned int file_id, - const unsigned char *uuid, unsigned int uuid_len) +static int tc_ns_need_load_image(const struct tc_ns_dev_file *dev_file, + const unsigned char *uuid, unsigned int uuid_len, struct tc_ns_client_return *tee_ret) { int ret; int smc_ret; @@ -266,10 +285,6 @@ static int tc_ns_need_load_image(unsigned int file_id, struct mb_cmd_pack *mb_pack = NULL; char *mb_param = NULL; - if (!uuid || uuid_len != UUID_LEN) { - tloge("invalid uuid\n"); - return -ENOMEM; - } mb_pack = mailbox_alloc_cmd_pack(); if (!mb_pack) { tloge("alloc mb pack failed\n"); @@ -289,7 +304,10 @@ static int tc_ns_need_load_image(unsigned int file_id, mb_pack->operation.params[0].memref.size = SZ_4K; smc_cmd.cmd_id = GLOBAL_CMD_ID_NEED_LOAD_APP; smc_cmd.cmd_type = CMD_TYPE_GLOBAL; - smc_cmd.dev_file_id = file_id; + smc_cmd.dev_file_id = dev_file->dev_file_id; +#ifdef CONFIG_CONFIDENT_CONAINER + smc_cmd.nsid = dev_file->nsid; +#endif smc_cmd.context_id = 0; smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation); smc_cmd.operation_h_phys = @@ -298,6 +316,10 @@ static int tc_ns_need_load_image(unsigned int file_id, smc_ret = tc_ns_smc(&smc_cmd); if (smc_ret != 0) { tloge("smc call returns error ret 0x%x\n", smc_ret); + if(smc_cmd.err_origin != TEEC_ORIGIN_COMMS && ret != NULL) { + tee_ret->origin = smc_cmd.err_origin; + tee_ret->code = smc_ret; + } ret = -EFAULT; goto clean; } else { @@ -311,19 +333,48 @@ clean: return ret; } +static int init_ioctl_args(struct tc_ns_dev_file *dev_file, const void __user *argp, + const struct load_secfile_ioctl_args *k_argp, struct load_secfile_ioctl_args *ioctl_arg) +{ + if (!dev_file) { + tloge("dev file is null\n"); + return -EINVAL; + } + if (dev_file->kernel_api != TEE_REQ_FROM_KERNEL_MODE) { + if(!argp) { + tloge("argp is null\n"); + return -EINVAL; + } + if(copy_from_user(ioctl_arg, argp, sizeof(*ioctl_arg))) { + tloge("copy from user failed\n"); + return -ENOMEM; + } + } else { + if(!k_argp) { + tloge("k_argp is null\n"); + return -EINVAL; + } + if (memcpy_s(ioctl_arg, sizeof(*ioctl_arg), k_arg, sizeof(*ioctl_arg)) != EOK) { + tloge("memcpy arg err\n"); + return -ENOMEM; + } + } + return 0; +} + int tc_ns_load_secfile(struct tc_ns_dev_file *dev_file, - void __user *argp, bool is_from_client_node) + void __user *argp, const struct load_secfile_ioctl_struct *k_argp, bool is_from_client_node) { int ret; struct load_secfile_ioctl_struct ioctl_arg = { {0}, {0}, {NULL} }; bool load = true; void *file_addr = NULL; - if (!dev_file || !argp) { - tloge("Invalid params !\n"); - return -EINVAL; + ret = init_ioctl_args(dev_file, argp, k_argp, &ioctl_arg); + if (ret != 0) { + tloge("init ioctl args failed\n"); + return ret; } - if (copy_from_user(&ioctl_arg, argp, sizeof(ioctl_arg)) != 0) { tloge("copy from user failed\n"); ret = -ENOMEM; @@ -348,7 +399,7 @@ int tc_ns_load_secfile(struct tc_ns_dev_file *dev_file, if (ioctl_arg.sec_file_info.secfile_type == LOAD_TA) { ret = tc_ns_need_load_image(dev_file->dev_file_id, ioctl_arg.uuid, - (unsigned int)UUID_LEN); + (unsigned int)UUID_LEN, NULL); if (ret != 1) /* 1 means we need to load image */ load = false; } @@ -362,8 +413,11 @@ int tc_ns_load_secfile(struct tc_ns_dev_file *dev_file, ioctl_arg.sec_file_info.secfile_type, ret); } mutex_unlock(&g_load_app_lock); - if (copy_to_user(argp, &ioctl_arg, sizeof(ioctl_arg)) != 0) - tloge("copy to user failed\n"); + if (dev_file->kernel_api != TEE_REQ_FROM_KERNEL_MODE) { + if (copy_to_user(argp, &ioctl_arg, sizeof(ioctl_arg)) != 0) + tloge("copy to user failed\n"); + } + return ret; } @@ -524,7 +578,7 @@ static int check_login_method(struct tc_ns_dev_file *dev_file, } static struct tc_ns_service *tc_ref_service_in_dev(struct tc_ns_dev_file *dev, - const unsigned char *uuid, int uuid_size, bool *is_full) + const unsigned char *uuid, int uuid_size, unsigned int nsid, bool *is_full) { uint32_t i; @@ -532,7 +586,7 @@ static struct tc_ns_service *tc_ref_service_in_dev(struct tc_ns_dev_file *dev, return NULL; for (i = 0; i < SERVICES_MAX_COUNT; i++) { - if (dev->services[i] != NULL && + if (dev->services[i] != NULL && dev->services[i]->nisid == nsid && memcmp(dev->services[i]->uuid, uuid, UUID_LEN) == 0) { if (dev->service_ref[i] == MAX_REF_COUNT) { *is_full = true; @@ -565,6 +619,11 @@ static int tc_ns_service_init(const unsigned char *uuid, uint32_t uuid_len, kfree(service); return -EFAULT; } +#ifdef CONFIG_CONFIDENT_CONAINER + service->nsid = task_active_pid_ns(current)->ns.inum; +#else + service->nsid = PROC_PID_INO; +#endif INIT_LIST_HEAD(&service->session_list); mutex_init(&service->session_lock); @@ -578,7 +637,7 @@ static int tc_ns_service_init(const unsigned char *uuid, uint32_t uuid_len, } static struct tc_ns_service *tc_find_service_from_all( - const unsigned char *uuid, uint32_t uuid_len) + const unsigned char *uuid, uint32_t uuid_len, uint32_t nsid) { struct tc_ns_service *service = NULL; @@ -586,7 +645,7 @@ static struct tc_ns_service *tc_find_service_from_all( return NULL; list_for_each_entry(service, &g_service_list, head) { - if (memcmp(service->uuid, uuid, sizeof(service->uuid)) == 0) + if (memcmp(service->uuid, uuid, sizeof(service->uuid)) == 0 && service->nsid == nsid) return service; } @@ -599,10 +658,15 @@ static struct tc_ns_service *find_service(struct tc_ns_dev_file *dev_file, int ret; struct tc_ns_service *service = NULL; bool is_full = false; +#ifdef CONFIG_CONFIDENT_CONAINER + unsigned int nsid = dev_file->nsid; +#else + unsigned int nsid = PROC_PID_INIT_INO; +#endif mutex_lock(&dev_file->service_lock); service = tc_ref_service_in_dev(dev_file, context->uuid, - UUID_LEN, &is_full); + UUID_LEN, nsid, &is_full); /* if service has been opened in this dev or ref cnt is full */ if (service || is_full) { /* @@ -616,7 +680,7 @@ static struct tc_ns_service *find_service(struct tc_ns_dev_file *dev_file, return service; } mutex_lock(&g_service_list_lock); - service = tc_find_service_from_all(context->uuid, UUID_LEN); + service = tc_find_service_from_all(context->uuid, UUID_LEN, nsid); /* if service has been opened in other dev */ if (service) { get_service_struct(service); @@ -779,6 +843,9 @@ static int load_image_by_frame(struct load_img_params *params, unsigned int load params->mb_pack->operation.params[3].value.a = index; params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type; smc_cmd.dev_file_id = params->dev_file->dev_file_id; +#ifdef CONFIG_CONFIDENT_CONAINER + smc_cmd.nsid = dev_file->nsid; +#endif smc_ret = tc_ns_smc(&smc_cmd); tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n", params->mb_pack->operation.params[1].value.a, smc_ret, @@ -927,6 +994,11 @@ static int load_ta_image(struct tc_ns_dev_file *dev_file, return ret; } } + if (ret != 0; tee_ret.orgin != TEEC_ORIGIN_COMMS) { + context->returns.code = tee_ret.code; + context->returns.origin = tee_ret.origin; + ret = EFAULT; + } mutex_unlock(&g_load_app_lock); return ret; @@ -959,6 +1031,9 @@ static int proc_open_session(struct tc_ns_dev_file *dev_file, }; mutex_lock(&service->operation_lock); + + if (lock_interruptible(&service->operation_lock) != 0) + return -EINTR; ret = load_ta_image(dev_file, context); if (ret != 0) { tloge("load ta image failed\n"); @@ -1038,7 +1113,11 @@ int tc_ns_open_session(struct tc_ns_dev_file *dev_file, tloge("calc client auth hash failed\n"); goto err_free_rsrc; } - +#ifdef CONFIG_CONFIDENT_CONAINER + if (dev_file->nsid ==0) { + dev_file->nsid = task_active_pid_ns(current)->ns.inun; + } +#endif ret = proc_open_session(dev_file, context, service, session, flags); if (ret == 0) goto err_clear_param; @@ -1186,7 +1265,10 @@ void close_unclosed_session_in_kthread(struct tc_ns_dev_file *dev) /* when self recovery, release session in reboot interface */ if (is_tee_rebooting()) return; - +#ifdef CONFIG_TA_AFFINITY + close_session_thread_fn(dev); + close_thread; +#else close_thread = kthread_create(close_session_thread_fn, dev, "close_fn_%6d", dev->dev_file_id); if (unlikely(IS_ERR_OR_NULL(close_thread))) { @@ -1198,6 +1280,7 @@ void close_unclosed_session_in_kthread(struct tc_ns_dev_file *dev) wake_up_process(close_thread); wait_for_completion(&dev->close_comp); tlogd("wait for completion success\n"); +#endif } int tc_ns_close_session(struct tc_ns_dev_file *dev_file, @@ -1227,7 +1310,10 @@ int tc_ns_close_session(struct tc_ns_dev_file *dev_file, * same session_id may appear in tzdriver, put session_list * add/del in service->operation_lock can avoid it. */ - mutex_lock(&service->operation_lock); + if(lock_interruptible(&service->operation_lock) !=0) { + tloge("lock_interruptible failed\n"); + return -EINTR; + } session = get_session(service, dev_file, context); if (session) { int ret2; diff --git a/core/session_manager.h b/core/session_manager.h index 4a08bf0..7c224a7 100644 --- a/core/session_manager.h +++ b/core/session_manager.h @@ -43,7 +43,7 @@ struct tc_ns_session *tc_find_session_withowner( const struct list_head *session_list, unsigned int session_id, const struct tc_ns_dev_file *dev_file); int tc_ns_load_secfile(struct tc_ns_dev_file *dev_file, - void __user *argp, bool is_from_client_node); + void __user *argp, const struct load_secfile_ioctl_args *k_argp, bool is_from_client_node); int load_image(struct load_img_params *params, struct sec_file_info *sec_file_info, struct tc_ns_client_return *tee_ret); void get_service_struct(struct tc_ns_service *service); diff --git a/core/shared_mem.h b/core/shared_mem.h index a0d4176..eff23bb 100644 --- a/core/shared_mem.h +++ b/core/shared_mem.h @@ -30,6 +30,14 @@ typedef struct page mailbox_page_t; typedef uintptr_t mailbox_page_t; #endif +struct pagelist_info { + uint64_t page_num; + uint64_t page_size; + uint64_t sharedmem_offset; + uint64_t sharedmem_size; +}; + +uint64_t get_reserved_cmd_vaddr_of(phys_addr_t cmd_phys, uint64_t cmd_size); int load_tz_shared_mem(struct device_node *np); mailbox_page_t *mailbox_alloc_pages(int order); @@ -38,6 +46,8 @@ uintptr_t mailbox_page_address(mailbox_page_t *page); mailbox_page_t *mailbox_virt_to_page(uint64_t ptr); uint64_t get_operation_vaddr(void); void free_operation(uint64_t op_vaddr); +uint64_t get_mailbox_buffer_vaddr(uint32_t pool_count); +void free_mailbox_buffer(uint64_t op_vaddr); uint64_t get_log_mem_vaddr(void); uint64_t get_log_mem_paddr(uint64_t log_vaddr); @@ -51,4 +61,8 @@ void free_cmd_mem(uint64_t cmd_vaddr); uint64_t get_spi_mem_vaddr(void); uint64_t get_spi_mem_paddr(uintptr_t spi_vaddr); void free_spi_mem(uint64_t spi_vaddr); +#ifdef CONFIG_NOCPY_SHAREDMEM +int fill_shared_mem_info(unint64_t start_vadd, uint32_t pages_no, + uint32_t offset, uint32_t buffer_size, uint64_t buf_size); +void release_shared_mem_pages(uint64_t buf, uint32_t buf_size); #endif diff --git a/core/tz_spi_notify.c b/core/tz_spi_notify.c index 587ef49..8ac5d64 100644 --- a/core/tz_spi_notify.c +++ b/core/tz_spi_notify.c @@ -400,7 +400,7 @@ static void tc_notify_set_affinity(struct notify_data_entry *entry) uint32_t i; cpumask_clear(&mask); - for (i = 0; i < (uint32_t)NR_CPUS; i++) { + for_each_online_cpu(i) { struct aff_bits_t *aff = &af_data->aff; if (aff->aff_bits[i / AFF_BITS_SIZE] & aff_bits_mask(i)) cpumask_set_cpu(i, &mask); @@ -581,18 +581,12 @@ int TC_NS_RegisterServiceCallbackFunc(const char *uuid, void *func, const void *private_data) { const char *uuid_in = uuid; + if(!get_tz_init_flag()) return EFAULT; return tc_ns_register_service_call_back_func(uuid_in, func, private_data); } EXPORT_SYMBOL(TC_NS_RegisterServiceCallbackFunc); -int tc_ns_tst_cmd(void *argp) -{ - (void)argp; - tloge("usr img do not support this cmd\n"); - return 0; -} - int send_notify_cmd(unsigned int cmd_id) { struct tc_ns_smc_cmd smc_cmd = { {0}, 0 }; @@ -619,7 +613,7 @@ int send_notify_cmd(unsigned int cmd_id) (unsigned int)((uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM); if (is_tee_rebooting()) - ret = send_smc_cmd_rebooting(TSP_REQUEST, 0, 0, &smc_cmd); + ret = send_smc_cmd_rebooting(TSP_REQUEST, &smc_cmd); else ret = tc_ns_smc(&smc_cmd); diff --git a/core/tz_spi_notify.h b/core/tz_spi_notify.h index 1722dc3..1469559 100644 --- a/core/tz_spi_notify.h +++ b/core/tz_spi_notify.h @@ -23,7 +23,6 @@ int tz_spi_init(struct device *class_dev, struct device_node *np); void free_tz_spi(struct device *class_dev); -int tc_ns_tst_cmd(void *argp); int send_notify_cmd(unsigned int cmd_id); #endif -- Gitee