[Skiboot] [RFC PATCH 07/10] keystore: add opal_set_variable runtime service
Eric Richter
erichte at linux.ibm.com
Thu Aug 2 08:53:46 AEST 2018
The opal_set_variable runtime service operates the same way for the active
bank and update queue; it updates an existing variable name's associated
data with the supplied data blob if the requested name exists. If the
requested name does not exist, it appends a new entry in the list.
NOTE: This runtime service does not do any size checks, and is the
likely candidate to do some form of size checking. Since we are holding
the keys in a sparse structure in memory, this service should probably
either use a routine to calculate the current total size, or a total
size value should be maintained either in the list head or globally.
Signed-off-by: Eric Richter <erichte at linux.ibm.com>
---
libstb/keystore.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/libstb/keystore.c b/libstb/keystore.c
index 8e19dbb6..8f825f8e 100644
--- a/libstb/keystore.c
+++ b/libstb/keystore.c
@@ -87,6 +87,66 @@ found:
opal_call(OPAL_GET_VARIABLE, opal_get_variable, 4);
+static int64_t opal_set_variable(uint64_t k_varname, uint64_t k_vardata, uint64_t varsize, uint64_t section)
+{
+ char *varname = (char*) k_varname;
+ char *vardata = (char*) k_vardata;
+
+ struct keystore_variable *var = NULL;
+
+ struct list_head *bank;
+
+ CHECK_KEYSTORE_READY;
+
+ bank = GET_BANK(section);
+
+ list_for_each(bank, var, link) {
+ if (!strcmp(varname, var->name)) {
+ goto found;
+ }
+ }
+
+ var = (struct keystore_variable *) malloc(sizeof(struct keystore_variable));
+ if (!var) {
+ prlog(PR_ERR, "Failed to allocate new variable\n");
+ return OPAL_NO_MEM;
+ }
+
+ var->name_size = strlen(varname) + 1;
+ var->name = malloc(var->name_size);
+ var->name[var->name_size] = '\0'; // Ensure print-friendly NULL terminator
+ if (!var->name) {
+ prlog(PR_ERR, "Failed to allocate new variable's name\n");
+ return OPAL_NO_MEM;
+ }
+
+ memcpy(var->name, varname, var->name_size);
+ var->data = NULL;
+
+ // Add to the list before moving to the shared behavior portion
+ list_add_tail(bank, &var->link);
+
+found:
+ // Clear old data if this is not a new variable.
+ if (var->data)
+ free(var->data);
+
+ var->data_size = varsize;
+ var->data = malloc(var->data_size);
+ if (!var->data) {
+ prlog(PR_ERR, "Failed to allocate new variable's data\n");
+ // TODO: we should probably clean up the linked list node if there is an error
+ // maybe we should try allocating data before freeing the old?
+ return OPAL_NO_MEM;
+ }
+
+ memcpy(var->data, vardata, var->data_size);
+
+ return OPAL_SUCCESS;
+}
+opal_call(OPAL_SET_VARIABLE, opal_set_variable, 4);
+
+
int keystore_init(void)
{
int rc;
--
2.14.4
More information about the Skiboot
mailing list