1*22ada947SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 2*22ada947SEtienne Carriere /* 3*22ada947SEtienne Carriere * Copyright (c) 2014-2020, Linaro Limited 4*22ada947SEtienne Carriere */ 5*22ada947SEtienne Carriere 6*22ada947SEtienne Carriere #include <stdlib.h> 7*22ada947SEtienne Carriere #include <tee_internal_api.h> 8*22ada947SEtienne Carriere #include <tee_internal_api_extensions.h> 9*22ada947SEtienne Carriere 10*22ada947SEtienne Carriere #include "handle.h" 11*22ada947SEtienne Carriere 12*22ada947SEtienne Carriere /* 13*22ada947SEtienne Carriere * Define the initial capacity of the database. It should be a low number 14*22ada947SEtienne Carriere * multiple of 2 since some databases a likely to only use a few handles. 15*22ada947SEtienne Carriere * Since the algorithm is to doubles up when growing it shouldn't cause a 16*22ada947SEtienne Carriere * noticeable overhead on large databases. 17*22ada947SEtienne Carriere */ 18*22ada947SEtienne Carriere #define HANDLE_DB_INITIAL_MAX_PTRS 4 19*22ada947SEtienne Carriere 20*22ada947SEtienne Carriere void handle_db_init(struct handle_db *db) 21*22ada947SEtienne Carriere { 22*22ada947SEtienne Carriere TEE_MemFill(db, 0, sizeof(*db)); 23*22ada947SEtienne Carriere } 24*22ada947SEtienne Carriere 25*22ada947SEtienne Carriere void handle_db_destroy(struct handle_db *db) 26*22ada947SEtienne Carriere { 27*22ada947SEtienne Carriere if (db) { 28*22ada947SEtienne Carriere TEE_Free(db->ptrs); 29*22ada947SEtienne Carriere db->ptrs = NULL; 30*22ada947SEtienne Carriere db->max_ptrs = 0; 31*22ada947SEtienne Carriere } 32*22ada947SEtienne Carriere } 33*22ada947SEtienne Carriere 34*22ada947SEtienne Carriere uint32_t handle_get(struct handle_db *db, void *ptr) 35*22ada947SEtienne Carriere { 36*22ada947SEtienne Carriere uint32_t n = 0; 37*22ada947SEtienne Carriere void *p = NULL; 38*22ada947SEtienne Carriere uint32_t new_max_ptrs = 0; 39*22ada947SEtienne Carriere 40*22ada947SEtienne Carriere if (!db || !ptr) 41*22ada947SEtienne Carriere return 0; 42*22ada947SEtienne Carriere 43*22ada947SEtienne Carriere /* Try to find an empty location (index 0 is reserved as invalid) */ 44*22ada947SEtienne Carriere for (n = 1; n < db->max_ptrs; n++) { 45*22ada947SEtienne Carriere if (!db->ptrs[n]) { 46*22ada947SEtienne Carriere db->ptrs[n] = ptr; 47*22ada947SEtienne Carriere return n; 48*22ada947SEtienne Carriere } 49*22ada947SEtienne Carriere } 50*22ada947SEtienne Carriere 51*22ada947SEtienne Carriere /* No location available, grow the ptrs array */ 52*22ada947SEtienne Carriere if (db->max_ptrs) 53*22ada947SEtienne Carriere new_max_ptrs = db->max_ptrs * 2; 54*22ada947SEtienne Carriere else 55*22ada947SEtienne Carriere new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; 56*22ada947SEtienne Carriere 57*22ada947SEtienne Carriere p = TEE_Realloc(db->ptrs, new_max_ptrs * sizeof(void *)); 58*22ada947SEtienne Carriere if (!p) 59*22ada947SEtienne Carriere return 0; 60*22ada947SEtienne Carriere db->ptrs = p; 61*22ada947SEtienne Carriere TEE_MemFill(db->ptrs + db->max_ptrs, 0, 62*22ada947SEtienne Carriere (new_max_ptrs - db->max_ptrs) * sizeof(void *)); 63*22ada947SEtienne Carriere db->max_ptrs = new_max_ptrs; 64*22ada947SEtienne Carriere 65*22ada947SEtienne Carriere /* Since n stopped at db->max_ptrs there is an empty location there */ 66*22ada947SEtienne Carriere db->ptrs[n] = ptr; 67*22ada947SEtienne Carriere return n; 68*22ada947SEtienne Carriere } 69*22ada947SEtienne Carriere 70*22ada947SEtienne Carriere void *handle_put(struct handle_db *db, uint32_t handle) 71*22ada947SEtienne Carriere { 72*22ada947SEtienne Carriere void *p = NULL; 73*22ada947SEtienne Carriere 74*22ada947SEtienne Carriere if (!db || !handle || handle >= db->max_ptrs) 75*22ada947SEtienne Carriere return NULL; 76*22ada947SEtienne Carriere 77*22ada947SEtienne Carriere p = db->ptrs[handle]; 78*22ada947SEtienne Carriere db->ptrs[handle] = NULL; 79*22ada947SEtienne Carriere return p; 80*22ada947SEtienne Carriere } 81*22ada947SEtienne Carriere 82*22ada947SEtienne Carriere void *handle_lookup(struct handle_db *db, uint32_t handle) 83*22ada947SEtienne Carriere { 84*22ada947SEtienne Carriere if (!db || !handle || handle >= db->max_ptrs) 85*22ada947SEtienne Carriere return NULL; 86*22ada947SEtienne Carriere 87*22ada947SEtienne Carriere return db->ptrs[handle]; 88*22ada947SEtienne Carriere } 89*22ada947SEtienne Carriere 90*22ada947SEtienne Carriere uint32_t handle_lookup_handle(struct handle_db *db, void *ptr) 91*22ada947SEtienne Carriere { 92*22ada947SEtienne Carriere uint32_t n = 0; 93*22ada947SEtienne Carriere 94*22ada947SEtienne Carriere if (ptr) { 95*22ada947SEtienne Carriere for (n = 1; n < db->max_ptrs; n++) 96*22ada947SEtienne Carriere if (db->ptrs[n] == ptr) 97*22ada947SEtienne Carriere return n; 98*22ada947SEtienne Carriere } 99*22ada947SEtienne Carriere 100*22ada947SEtienne Carriere return 0; 101*22ada947SEtienne Carriere } 102