122ada947SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 222ada947SEtienne Carriere /* 322ada947SEtienne Carriere * Copyright (c) 2014-2020, Linaro Limited 422ada947SEtienne Carriere */ 522ada947SEtienne Carriere 622ada947SEtienne Carriere #include <stdlib.h> 722ada947SEtienne Carriere #include <tee_internal_api.h> 822ada947SEtienne Carriere #include <tee_internal_api_extensions.h> 922ada947SEtienne Carriere 1022ada947SEtienne Carriere #include "handle.h" 1122ada947SEtienne Carriere 1222ada947SEtienne Carriere /* 1322ada947SEtienne Carriere * Define the initial capacity of the database. It should be a low number 1422ada947SEtienne Carriere * multiple of 2 since some databases a likely to only use a few handles. 1522ada947SEtienne Carriere * Since the algorithm is to doubles up when growing it shouldn't cause a 1622ada947SEtienne Carriere * noticeable overhead on large databases. 1722ada947SEtienne Carriere */ 1822ada947SEtienne Carriere #define HANDLE_DB_INITIAL_MAX_PTRS 4 1922ada947SEtienne Carriere 2022ada947SEtienne Carriere void handle_db_init(struct handle_db *db) 2122ada947SEtienne Carriere { 2222ada947SEtienne Carriere TEE_MemFill(db, 0, sizeof(*db)); 2322ada947SEtienne Carriere } 2422ada947SEtienne Carriere 2522ada947SEtienne Carriere void handle_db_destroy(struct handle_db *db) 2622ada947SEtienne Carriere { 2722ada947SEtienne Carriere if (db) { 2822ada947SEtienne Carriere TEE_Free(db->ptrs); 2922ada947SEtienne Carriere db->ptrs = NULL; 3022ada947SEtienne Carriere db->max_ptrs = 0; 3122ada947SEtienne Carriere } 3222ada947SEtienne Carriere } 3322ada947SEtienne Carriere 3422ada947SEtienne Carriere uint32_t handle_get(struct handle_db *db, void *ptr) 3522ada947SEtienne Carriere { 3622ada947SEtienne Carriere uint32_t n = 0; 3722ada947SEtienne Carriere void *p = NULL; 3822ada947SEtienne Carriere uint32_t new_max_ptrs = 0; 3922ada947SEtienne Carriere 4022ada947SEtienne Carriere if (!db || !ptr) 4122ada947SEtienne Carriere return 0; 4222ada947SEtienne Carriere 4322ada947SEtienne Carriere /* Try to find an empty location (index 0 is reserved as invalid) */ 4422ada947SEtienne Carriere for (n = 1; n < db->max_ptrs; n++) { 4522ada947SEtienne Carriere if (!db->ptrs[n]) { 4622ada947SEtienne Carriere db->ptrs[n] = ptr; 4722ada947SEtienne Carriere return n; 4822ada947SEtienne Carriere } 4922ada947SEtienne Carriere } 5022ada947SEtienne Carriere 5122ada947SEtienne Carriere /* No location available, grow the ptrs array */ 5222ada947SEtienne Carriere if (db->max_ptrs) 5322ada947SEtienne Carriere new_max_ptrs = db->max_ptrs * 2; 5422ada947SEtienne Carriere else 5522ada947SEtienne Carriere new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; 5622ada947SEtienne Carriere 5722ada947SEtienne Carriere p = TEE_Realloc(db->ptrs, new_max_ptrs * sizeof(void *)); 5822ada947SEtienne Carriere if (!p) 5922ada947SEtienne Carriere return 0; 6022ada947SEtienne Carriere db->ptrs = p; 6122ada947SEtienne Carriere TEE_MemFill(db->ptrs + db->max_ptrs, 0, 6222ada947SEtienne Carriere (new_max_ptrs - db->max_ptrs) * sizeof(void *)); 6322ada947SEtienne Carriere db->max_ptrs = new_max_ptrs; 6422ada947SEtienne Carriere 6522ada947SEtienne Carriere /* Since n stopped at db->max_ptrs there is an empty location there */ 6622ada947SEtienne Carriere db->ptrs[n] = ptr; 6722ada947SEtienne Carriere return n; 6822ada947SEtienne Carriere } 6922ada947SEtienne Carriere 70*b8fa5170SEtienne Carriere static bool handle_is_valid(struct handle_db *db, uint32_t handle) 71*b8fa5170SEtienne Carriere { 72*b8fa5170SEtienne Carriere return db && handle && handle < db->max_ptrs; 73*b8fa5170SEtienne Carriere } 74*b8fa5170SEtienne Carriere 7522ada947SEtienne Carriere void *handle_put(struct handle_db *db, uint32_t handle) 7622ada947SEtienne Carriere { 7722ada947SEtienne Carriere void *p = NULL; 7822ada947SEtienne Carriere 79*b8fa5170SEtienne Carriere if (!handle_is_valid(db, handle)) 8022ada947SEtienne Carriere return NULL; 8122ada947SEtienne Carriere 8222ada947SEtienne Carriere p = db->ptrs[handle]; 8322ada947SEtienne Carriere db->ptrs[handle] = NULL; 8422ada947SEtienne Carriere return p; 8522ada947SEtienne Carriere } 8622ada947SEtienne Carriere 8722ada947SEtienne Carriere void *handle_lookup(struct handle_db *db, uint32_t handle) 8822ada947SEtienne Carriere { 89*b8fa5170SEtienne Carriere if (!handle_is_valid(db, handle)) 9022ada947SEtienne Carriere return NULL; 9122ada947SEtienne Carriere 9222ada947SEtienne Carriere return db->ptrs[handle]; 9322ada947SEtienne Carriere } 9422ada947SEtienne Carriere 9522ada947SEtienne Carriere uint32_t handle_lookup_handle(struct handle_db *db, void *ptr) 9622ada947SEtienne Carriere { 9722ada947SEtienne Carriere uint32_t n = 0; 9822ada947SEtienne Carriere 9922ada947SEtienne Carriere if (ptr) { 10022ada947SEtienne Carriere for (n = 1; n < db->max_ptrs; n++) 10122ada947SEtienne Carriere if (db->ptrs[n] == ptr) 10222ada947SEtienne Carriere return n; 10322ada947SEtienne Carriere } 10422ada947SEtienne Carriere 10522ada947SEtienne Carriere return 0; 10622ada947SEtienne Carriere } 107