summaryrefslogtreecommitdiff
path: root/src/tspi/tsp_context_mem.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-11-25 14:36:20 +0000
commitc3649a2def02c41d837ae1f79dda729ccb91e677 (patch)
treebea46dff212fdef977fe9094a70a939e8cc21885 /src/tspi/tsp_context_mem.c
downloadtrousers-upstream/0.3.9.tar.gz
Imported Upstream version 0.3.9upstream/0.3.9upstream
Diffstat (limited to 'src/tspi/tsp_context_mem.c')
-rw-r--r--src/tspi/tsp_context_mem.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/tspi/tsp_context_mem.c b/src/tspi/tsp_context_mem.c
new file mode 100644
index 0000000..13f1243
--- /dev/null
+++ b/src/tspi/tsp_context_mem.c
@@ -0,0 +1,258 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "spi_utils.h"
+#include "capabilities.h"
+#include "memmgr.h"
+#include "tsplog.h"
+#include "obj.h"
+
+static struct memTable *
+__tspi_createTable()
+{
+ struct memTable *table = NULL;
+ /*
+ * No table has yet been created to hold the memory allocations of
+ * this context, so we need to create one
+ */
+ table = calloc(1, sizeof(struct memTable));
+ if (table == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct memTable));
+ return NULL;
+ }
+ return (table);
+}
+
+/* caller needs to lock memtable lock */
+struct memTable *
+getTable(TSS_HCONTEXT tspContext)
+{
+ struct memTable *tmp;
+
+ for (tmp = SpiMemoryTable; tmp; tmp = tmp->nextTable)
+ if (tmp->tspContext == tspContext)
+ return tmp;
+
+ return NULL;
+}
+
+/* caller needs to lock memtable lock */
+static void
+__tspi_addTable(struct memTable *new)
+{
+ struct memTable *tmp = SpiMemoryTable;
+
+ /* base case, this is the first table */
+ if (SpiMemoryTable == NULL) {
+ SpiMemoryTable = new;
+ return;
+ }
+
+ /* else add @new onto the end */
+ for (; tmp; tmp = tmp->nextTable)
+ if (tmp->nextTable == NULL) {
+ tmp->nextTable = new;
+ break;
+ }
+}
+
+/* caller needs to lock memtable lock and be sure the context mem slot for
+ * @tspContext exists before calling.
+ */
+void
+__tspi_addEntry(TSS_HCONTEXT tspContext, struct memEntry *new)
+{
+ struct memTable *tmp = getTable(tspContext);
+ struct memEntry *tmp_entry;
+
+ if (tmp == NULL) {
+ if ((tmp = __tspi_createTable()) == NULL)
+ return;
+ tmp->tspContext = tspContext;
+ __tspi_addTable(tmp);
+ }
+
+ tmp_entry = tmp->entries;
+
+ if (tmp->entries == NULL) {
+ tmp->entries = new;
+ return;
+ }
+
+ /* else tack @new onto the end */
+ for (; tmp_entry; tmp_entry = tmp_entry->nextEntry) {
+ if (tmp_entry->nextEntry == NULL) {
+ tmp_entry->nextEntry = new;
+ break;
+ }
+ }
+}
+
+/* caller needs to lock memtable lock */
+TSS_RESULT
+__tspi_freeTable(TSS_HCONTEXT tspContext)
+{
+ struct memTable *prev = NULL, *index = NULL, *next = NULL;
+ struct memEntry *entry = NULL, *entry_next = NULL;
+
+ for(index = SpiMemoryTable; index; index = index->nextTable) {
+ next = index->nextTable;
+ if (index->tspContext == tspContext) {
+ for (entry = index->entries; entry; entry = entry_next) {
+ /* this needs to be set before we do free(entry) */
+ entry_next = entry->nextEntry;
+ free(entry->memPointer);
+ free(entry);
+ }
+
+ if (prev != NULL)
+ prev->nextTable = next;
+ else
+ SpiMemoryTable = NULL;
+
+ free(index);
+ break;
+ }
+ prev = index;
+ }
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+__tspi_freeEntry(struct memTable *table, void *pointer)
+{
+ struct memEntry *index = NULL;
+ struct memEntry *prev = NULL;
+ struct memEntry *toKill = NULL;
+
+ for (index = table->entries; index; prev = index, index = index->nextEntry) {
+ if (index->memPointer == pointer) {
+ toKill = index;
+ if (prev == NULL)
+ table->entries = toKill->nextEntry;
+ else
+ prev->nextEntry = toKill->nextEntry;
+
+ free(pointer);
+ free(toKill);
+ return TSS_SUCCESS;
+ }
+ }
+
+ return TSPERR(TSS_E_INVALID_RESOURCE);
+}
+
+TSS_RESULT
+__tspi_add_mem_entry(TSS_HCONTEXT tspContext, void *allocd_mem)
+{
+ struct memEntry *newEntry = calloc(1, sizeof(struct memEntry));
+ if (newEntry == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct memEntry));
+ return TSPERR(TSS_E_OUTOFMEMORY);
+ }
+
+ newEntry->memPointer = allocd_mem;
+
+ MUTEX_LOCK(memtable_lock);
+
+ __tspi_addEntry(tspContext, newEntry);
+
+ MUTEX_UNLOCK(memtable_lock);
+
+ return TSS_SUCCESS;
+}
+
+/*
+ * calloc_tspi will be called by functions outside of this file. All locking
+ * is done here.
+ */
+void *
+calloc_tspi(TSS_HCONTEXT tspContext, UINT32 howMuch)
+{
+ struct memTable *table = NULL;
+ struct memEntry *newEntry = NULL;
+
+ MUTEX_LOCK(memtable_lock);
+
+ table = getTable(tspContext);
+ if (table == NULL) {
+ if ((table = __tspi_createTable()) == NULL) {
+ MUTEX_UNLOCK(memtable_lock);
+ return NULL;
+ }
+ table->tspContext = tspContext;
+ __tspi_addTable(table);
+ }
+
+ newEntry = calloc(1, sizeof(struct memEntry));
+ if (newEntry == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct memEntry));
+ MUTEX_UNLOCK(memtable_lock);
+ return NULL;
+ }
+
+ newEntry->memPointer = calloc(1, howMuch);
+ if (newEntry->memPointer == NULL) {
+ LogError("malloc of %d bytes failed.", howMuch);
+ free(newEntry);
+ MUTEX_UNLOCK(memtable_lock);
+ return NULL;
+ }
+
+ /* this call must happen inside the lock or else another thread could
+ * remove the context mem slot, causing a segfault
+ */
+ __tspi_addEntry(tspContext, newEntry);
+
+ MUTEX_UNLOCK(memtable_lock);
+
+ return newEntry->memPointer;
+}
+
+/*
+ * free_tspi will be called by functions outside of this file. All locking
+ * is done here.
+ */
+TSS_RESULT
+free_tspi(TSS_HCONTEXT tspContext, void *memPointer)
+{
+ struct memTable *index;
+ TSS_RESULT result;
+
+ MUTEX_LOCK(memtable_lock);
+
+ if (memPointer == NULL) {
+ result = __tspi_freeTable(tspContext);
+ MUTEX_UNLOCK(memtable_lock);
+ return result;
+ }
+
+ if ((index = getTable(tspContext)) == NULL) {
+ MUTEX_UNLOCK(memtable_lock);
+ /* Tspi_Context_FreeMemory checks that the TSP context is good before calling us,
+ * so we can be sure that the problem is with memPointer */
+ return TSPERR(TSS_E_INVALID_RESOURCE);
+ }
+
+ /* just free one entry */
+ result = __tspi_freeEntry(index, memPointer);
+
+ MUTEX_UNLOCK(memtable_lock);
+
+ return result;
+}