3
* Licensed Materials - Property of IBM
5
* trousers - An open source TCG Software Stack
7
* (C) Copyright International Business Machines Corp. 2004
16
#include "trousers/tss.h"
17
#include "spi_internal_types.h"
18
#include "spi_utils.h"
19
#include "capabilities.h"
24
/* caller needs to lock memtable lock */
26
getTable(TSS_HCONTEXT tspContext)
30
for (tmp = SpiMemoryTable; tmp; tmp = tmp->nextTable)
31
if (tmp->tspContext == tspContext)
37
/* caller needs to lock memtable lock and be sure the context mem slot for
38
* @tspContext exists before calling.
41
addEntry(TSS_HCONTEXT tspContext, struct memEntry *new)
43
struct memTable *tmp = getTable(tspContext);
44
struct memEntry *tmp_entry = tmp->entries;
46
if (tmp->entries == NULL) {
51
/* else tack @new onto the end */
52
for (; tmp_entry; tmp_entry = tmp_entry->nextEntry) {
53
if (tmp_entry->nextEntry == NULL) {
54
tmp_entry->nextEntry = new;
60
/* caller needs to lock memtable lock */
62
addTable(struct memTable *new)
64
struct memTable *tmp = SpiMemoryTable;
66
/* base case, this is the first table */
67
if (SpiMemoryTable == NULL) {
72
/* else add @new onto the end */
73
for (; tmp; tmp = tmp->nextTable)
74
if (tmp->nextTable == NULL) {
80
/* caller needs to lock memtable lock */
82
freeTable(TSS_HCONTEXT tspContext)
84
struct memTable *prev = NULL, *index = NULL, *next = NULL;
85
struct memEntry *entry = NULL, *entry_next = NULL;
87
for(index = SpiMemoryTable; index; index = index->nextTable) {
88
next = index->nextTable;
89
if (index->tspContext == tspContext) {
90
for (entry = index->entries; entry; entry = entry_next) {
91
/* this needs to be set before we do free(entry) */
92
entry_next = entry->nextEntry;
93
free(entry->memPointer);
98
prev->nextTable = next;
100
SpiMemoryTable = NULL;
112
freeEntry(struct memTable *table, void *pointer)
114
struct memEntry *index = NULL;
115
struct memEntry *prev = NULL;
116
struct memEntry *toKill = NULL;
118
for (index = table->entries; index; prev = index, index = index->nextEntry) {
119
if (index->memPointer == pointer) {
122
table->entries = toKill->nextEntry;
124
prev->nextEntry = toKill->nextEntry;
133
LogError("Internal error: pointer to allocated memory not found.");
134
return TSPERR(TSS_E_INTERNAL_ERROR);
138
add_mem_entry(TSS_HCONTEXT tspContext, void *allocd_mem)
140
struct memEntry *newEntry = calloc(1, sizeof(struct memEntry));
141
if (newEntry == NULL) {
142
LogError("malloc of %zd bytes failed.", sizeof(struct memEntry));
143
return TSPERR(TSS_E_OUTOFMEMORY);
146
newEntry->memPointer = allocd_mem;
148
pthread_mutex_lock(&memtable_lock);
150
addEntry(tspContext, newEntry);
152
pthread_mutex_unlock(&memtable_lock);
158
* calloc_tspi will be called by functions outside of this file. All locking
162
calloc_tspi(TSS_HCONTEXT tspContext, UINT32 howMuch)
164
struct memTable *table = NULL;
165
struct memEntry *newEntry = NULL;
167
pthread_mutex_lock(&memtable_lock);
169
table = getTable(tspContext);
171
/* no table has yet been created to hold the memory allocations of
172
* this context, so we need to create one
174
table = calloc(1, sizeof(struct memTable));
176
LogError("malloc of %zd bytes failed.", sizeof(struct memTable));
177
pthread_mutex_unlock(&memtable_lock);
180
table->tspContext = tspContext;
184
newEntry = calloc(1, sizeof(struct memEntry));
185
if (newEntry == NULL) {
186
LogError("malloc of %zd bytes failed.", sizeof(struct memEntry));
187
pthread_mutex_unlock(&memtable_lock);
191
newEntry->memPointer = calloc(1, howMuch);
192
if (newEntry->memPointer == NULL) {
193
LogError("malloc of %d bytes failed.", howMuch);
195
pthread_mutex_unlock(&memtable_lock);
199
/* this call must happen inside the lock or else another thread could
200
* remove the context mem slot, causing a segfault
202
addEntry(tspContext, newEntry);
204
pthread_mutex_unlock(&memtable_lock);
206
return newEntry->memPointer;
210
* free_tspi will be called by functions outside of this file. All locking
214
free_tspi(TSS_HCONTEXT tspContext, void *memPointer)
216
struct memTable *index;
219
pthread_mutex_lock(&memtable_lock);
221
if (memPointer == NULL) {
222
result = freeTable(tspContext);
223
pthread_mutex_unlock(&memtable_lock);
227
if ((index = getTable(tspContext)) == NULL) {
228
pthread_mutex_unlock(&memtable_lock);
229
return TSPERR(TSS_E_INVALID_HANDLE);
232
/* just free one entry */
233
result = freeEntry(index, memPointer);
235
pthread_mutex_unlock(&memtable_lock);