Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2019 IBM Corp. */
3 : :
4 : : #ifndef pr_fmt
5 : : #define pr_fmt(fmt) "SECVAR_API: " fmt
6 : : #endif
7 : :
8 : : #include <opal.h>
9 : : #include "secvar.h"
10 : :
11 : :
12 : 10 : static int64_t opal_secvar_get(const char *key, uint64_t key_len, void *data, uint64_t *data_size)
13 : : {
14 : : struct secvar *var;
15 : 10 : int64_t rc = OPAL_SUCCESS;
16 : :
17 : 10 : if (!secvar_enabled)
18 : 1 : return OPAL_UNSUPPORTED;
19 : 9 : if (!secvar_ready)
20 : 1 : return OPAL_RESOURCE;
21 : 8 : if (!key)
22 : 1 : return OPAL_PARAMETER;
23 : 7 : if (key_len == 0)
24 : 1 : return OPAL_PARAMETER;
25 : : // Data size must be set, data is optional for size query
26 : 6 : if (!data_size)
27 : 1 : return OPAL_PARAMETER;
28 : :
29 : 5 : var = find_secvar(key, key_len, &variable_bank);
30 : 5 : if (!var)
31 : 1 : return OPAL_EMPTY; // Variable not found, bail early
32 : :
33 : 4 : if (!data)
34 : 1 : rc = OPAL_SUCCESS;
35 : 3 : else if (*data_size < var->data_size)
36 : 2 : rc = OPAL_PARTIAL;
37 : : else
38 : 1 : memcpy(data, var->data, var->data_size);
39 : :
40 : 4 : *data_size = var->data_size;
41 : :
42 : 4 : return rc;
43 : : }
44 : : opal_call(OPAL_SECVAR_GET, opal_secvar_get, 4);
45 : :
46 : :
47 : 13 : static int64_t opal_secvar_get_next(char *key, uint64_t *key_len, uint64_t key_buf_size)
48 : : {
49 : : struct secvar *var;
50 : :
51 : 13 : if (!secvar_enabled)
52 : 1 : return OPAL_UNSUPPORTED;
53 : 12 : if (!secvar_ready)
54 : 1 : return OPAL_RESOURCE;
55 : 11 : if (!key_len)
56 : 1 : return OPAL_PARAMETER;
57 : 10 : if (key_buf_size == 0)
58 : 1 : return OPAL_PARAMETER;
59 : 9 : if (*key_len > SECVAR_MAX_KEY_LEN)
60 : 1 : return OPAL_PARAMETER;
61 : 8 : if (*key_len > key_buf_size)
62 : 1 : return OPAL_PARAMETER;
63 : 7 : if (!key)
64 : 1 : return OPAL_PARAMETER;
65 : :
66 : 6 : if (!is_key_empty(key, *key_len)) {
67 : 4 : var = find_secvar(key, *key_len, &variable_bank);
68 : 4 : if (!var)
69 : 1 : return OPAL_PARAMETER;
70 : :
71 : 3 : var = list_next(&variable_bank, var, link);
72 : : } else {
73 : 2 : var = list_top(&variable_bank, struct secvar, link);
74 : : }
75 : :
76 : 5 : if (!var)
77 : 1 : return OPAL_EMPTY;
78 : :
79 : 4 : if (key_buf_size < var->key_len) {
80 : 1 : *key_len = var->key_len;
81 : 1 : return OPAL_PARTIAL;
82 : : }
83 : :
84 : 3 : *key_len = var->key_len;
85 : 3 : memcpy(key, var->key, var->key_len);
86 : :
87 : 3 : return OPAL_SUCCESS;
88 : : }
89 : : opal_call(OPAL_SECVAR_GET_NEXT, opal_secvar_get_next, 3);
90 : :
91 : :
92 : 16 : static int64_t opal_secvar_enqueue_update(const char *key, uint64_t key_len, void *data, uint64_t data_size)
93 : : {
94 : : struct secvar *var;
95 : :
96 : 16 : if (!secvar_enabled)
97 : 1 : return OPAL_UNSUPPORTED;
98 : 15 : if (!secvar_ready)
99 : 1 : return OPAL_RESOURCE;
100 : 14 : if (!secvar_storage.write_bank)
101 : 1 : return OPAL_HARDWARE;
102 : 13 : if (!key)
103 : 1 : return OPAL_PARAMETER;
104 : 12 : if (key_len == 0)
105 : 1 : return OPAL_PARAMETER;
106 : 11 : if (key_len > SECVAR_MAX_KEY_LEN)
107 : 1 : return OPAL_PARAMETER;
108 : 10 : if ((!data) && (data_size != 0))
109 : 1 : return OPAL_PARAMETER;
110 : 9 : if (data_size > secvar_storage.max_var_size)
111 : 1 : return OPAL_PARAMETER;
112 : :
113 : : // Key should not be empty
114 : 8 : if (is_key_empty(key, key_len))
115 : 2 : return OPAL_PARAMETER;
116 : :
117 : 6 : var = find_secvar(key, key_len, &update_bank);
118 : :
119 : : // Unstage an update
120 : 6 : if (data_size == 0) {
121 : 2 : if (!var)
122 : 1 : return OPAL_EMPTY;
123 : :
124 : 1 : list_del(&var->link);
125 : 1 : dealloc_secvar(var);
126 : 1 : goto out;
127 : : }
128 : :
129 : 4 : if (var) {
130 : 1 : list_del(&var->link);
131 : : // Realloc var if too small
132 : 1 : if (var->data_size < data_size) {
133 : 0 : if (realloc_secvar(var, data_size))
134 : 0 : return OPAL_NO_MEM;
135 : : } else {
136 : 1 : memset(var->data, 0x00, var->data_size);
137 : : }
138 : : } else {
139 : 3 : var = alloc_secvar(key_len, data_size);
140 : 3 : if (!var)
141 : 0 : return OPAL_NO_MEM;
142 : : }
143 : :
144 : 4 : memcpy(var->key, key, key_len);
145 : 4 : var->key_len = key_len;
146 : 4 : memcpy(var->data, data, data_size);
147 : 4 : var->data_size = data_size;
148 : :
149 : 4 : list_add_tail(&update_bank, &var->link);
150 : :
151 : 5 : out:
152 : 5 : if (secvar_storage.write_bank(&update_bank, SECVAR_UPDATE_BANK))
153 : 0 : return OPAL_HARDWARE;
154 : : else
155 : 5 : return OPAL_SUCCESS;
156 : : }
157 : : opal_call(OPAL_SECVAR_ENQUEUE_UPDATE, opal_secvar_enqueue_update, 4);
|