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