summaryrefslogtreecommitdiff
path: root/common/new_nvmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/new_nvmem.c')
-rw-r--r--common/new_nvmem.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/common/new_nvmem.c b/common/new_nvmem.c
index 714481c0fb..60d8704a9b 100644
--- a/common/new_nvmem.c
+++ b/common/new_nvmem.c
@@ -312,7 +312,6 @@ static struct delete_candidates {
* list.
*/
static uint8_t page_list[NEW_NVMEM_TOTAL_PAGES];
-static uint8_t migration_in_progress;
static uint32_t next_evict_obj_base;
/*
@@ -1353,11 +1352,8 @@ static enum ec_error_list save_var(const uint8_t *key, uint8_t key_len,
vc->c_header.size = sizeof(struct tuple) + val_len + key_len;
rv = save_container(&vc->c_header);
- if (rv == EC_SUCCESS) {
+ if (rv == EC_SUCCESS)
total_var_space += key_len + val_len;
- if (!migration_in_progress)
- add_final_delimiter();
- }
if (local_alloc)
shared_mem_release(vc);
@@ -1445,10 +1441,8 @@ enum ec_error_list new_nvmem_migrate(unsigned int act_partition)
ch->encrypted = 1;
ch->generation = 0;
- migration_in_progress = 1;
migrate_vars(ch);
migrate_tpm_nvmem(ch);
- migration_in_progress = 0;
shared_mem_release(ch);
@@ -1888,6 +1882,10 @@ static enum ec_error_list verify_last_section(
union {
uint32_t handle; /* For evictables. */
uint8_t id; /* For reserved objects. */
+ struct { /* For tuples. */
+ uint32_t key_hash;
+ uint8_t key_len;
+ };
};
};
struct new_objects {
@@ -1900,6 +1898,7 @@ static enum ec_error_list verify_last_section(
struct object *po;
uint8_t ctype;
struct page_tracker top_del;
+ struct max_var_container *vc;
int i;
newobjs = get_scratch_buffer(sizeof(struct new_objects));
@@ -1926,6 +1925,14 @@ static enum ec_error_list verify_last_section(
case NN_OBJ_TPM_EVICTABLE:
po->handle = *((uint32_t *)(ch + 1));
break;
+
+ case NN_OBJ_TUPLE:
+ vc = (struct max_var_container *)ch;
+ po->key_len = vc->t_header.key_len;
+ app_compute_hash_wrapper(vc->t_header.data_,
+ po->key_len, &po->key_hash,
+ sizeof(po->key_hash));
+ break;
default:
continue;
}
@@ -1975,15 +1982,33 @@ static enum ec_error_list verify_last_section(
key = *((uint32_t *)(ch + 1));
key_size = sizeof(uint32_t);
break;
+
+ case NN_OBJ_TUPLE:
+ vc = (struct max_var_container *)ch;
+ key_size = vc->t_header.key_len;
+ app_compute_hash_wrapper(vc->t_header.data_, key_size,
+ &key, sizeof(key));
+ break;
+
default:
continue;
}
for (i = 0, po = newobjs->objects; i < newobjs->num_objects;
i++, po++) {
- if ((po->cont_type != ctype) ||
- ((key_size == 1) && (po->id != key)) ||
- ((key_size == 4) && (po->handle != key)))
+ if (po->cont_type != ctype)
+ continue;
+
+ if ((ctype == NN_OBJ_TPM_RESERVED) && (po->id != key))
+ continue;
+
+ if ((ctype == NN_OBJ_TPM_EVICTABLE) &&
+ (po->handle != key))
+ continue;
+
+ if ((ctype == NN_OBJ_TUPLE) &&
+ ((po->key_len != key_size) ||
+ (key != po->key_hash)))
continue;
/*
@@ -2056,11 +2081,8 @@ static enum ec_error_list verify_delimiter(struct nn_container *nc)
dpt.list_index = i;
}
- while ((rv = get_next_object(&dpt, nc, 0)) == EC_SUCCESS) {
- if (nc->container_type == NN_OBJ_TUPLE)
- continue;
+ while ((rv = get_next_object(&dpt, nc, 0)) == EC_SUCCESS)
delete_object(&dpt, nc);
- }
if (rv == EC_ERROR_INVAL) {
/*
@@ -2669,6 +2691,7 @@ int setvar(const uint8_t *key, uint8_t key_len, const uint8_t *val,
size_t old_var_space;
struct max_var_container *vc;
struct access_tracker at = {};
+ const struct nn_container *del;
if (!key || !key_len)
return EC_ERROR_INVAL;
@@ -2715,7 +2738,11 @@ int setvar(const uint8_t *key, uint8_t key_len, const uint8_t *val,
/* No, it will not. */
return EC_ERROR_OVERFLOW;
- return save_var(key, key_len, val, val_len, vc);
+ rv = save_var(key, key_len, val, val_len, vc);
+ if (rv == EC_SUCCESS)
+ add_final_delimiter();
+
+ return rv;
}
/* The variable was found, let's see if the value is being changed. */
@@ -2737,12 +2764,23 @@ int setvar(const uint8_t *key, uint8_t key_len, const uint8_t *val,
vc->c_header.generation++;
rv = save_var(key, key_len, val, val_len, vc);
shared_mem_release(vc);
+ del = page_cursor(&master_at.mt);
+#if defined(NVMEM_TEST_BUILD)
+ if (failure_mode == TEST_FAIL_SAVING_VAR)
+ return EC_SUCCESS;
+#endif
+ add_delimiter();
if (rv == EC_SUCCESS) {
rv = invalidate_object(
(struct nn_container *)((uintptr_t)at.ct.ph +
at.ct.data_offset));
- if (rv == EC_SUCCESS)
+ if (rv == EC_SUCCESS) {
total_var_space -= old_var_space;
+#if defined(NVMEM_TEST_BUILD)
+ if (failure_mode != TEST_FAIL_FINALIZING_VAR)
+#endif
+ finalize_delimiter(del);
+ }
}
return rv;
}