blob: 3283c9fe9d0a1d6ef9574da14697673ef6572dc8 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <attestation.h>
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +00007#include <buffer.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +00008#include <debug.h>
9#include <granule.h>
10#include <measurement.h>
11#include <realm.h>
AlexeiFedorov5b186ad2023-04-26 14:43:18 +010012#include <rsi-handler.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000013#include <smc-rsi.h>
14#include <smc.h>
15#include <string.h>
16#include <utils_def.h>
17
AlexeiFedorovefe2aec2023-06-08 16:17:00 +010018#define MAX_EXTENDED_SIZE (64U)
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010019#define MAX_MEASUREMENT_WORDS (MAX_MEASUREMENT_SIZE / sizeof(unsigned long))
Soby Mathewb4c6df42022-11-09 11:13:29 +000020/*
21 * Return the Realm Personalization Value.
22 *
23 * Arguments:
24 * rd - The Realm descriptor.
Mate Toth-Pal071aa562023-07-04 09:09:26 +020025 * claim_ptr - The start address of the Realm Personalization Value claim
26 * claim_len - The length of the Realm Personalization Value claim
Soby Mathewb4c6df42022-11-09 11:13:29 +000027 */
Mate Toth-Pal071aa562023-07-04 09:09:26 +020028static void get_rpv(struct rd *rd, void **claim_ptr, size_t *claim_len)
Soby Mathewb4c6df42022-11-09 11:13:29 +000029{
Mate Toth-Pal071aa562023-07-04 09:09:26 +020030 *claim_ptr = (uint8_t *)&(rd->rpv[0]);
31 *claim_len = RPV_SIZE;
Soby Mathewb4c6df42022-11-09 11:13:29 +000032}
33
34/*
AlexeiFedorov97844202023-04-27 15:17:35 +010035 * Function to continue with the token write operation
Soby Mathewb4c6df42022-11-09 11:13:29 +000036 */
37static void attest_token_continue_write_state(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +010038 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000039{
Soby Mathewb4c6df42022-11-09 11:13:29 +000040 struct granule *gr;
AlexeiFedorovea68b552023-10-03 11:11:47 +010041 uintptr_t realm_att_token;
Soby Mathewb4c6df42022-11-09 11:13:29 +000042 unsigned long realm_att_token_ipa = rec->regs[1];
AlexeiFedorovea68b552023-10-03 11:11:47 +010043 unsigned long offset = rec->regs[2];
44 unsigned long size = rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000045 enum s2_walk_status walk_status;
46 struct s2_walk_result walk_res = { 0UL };
AlexeiFedorovea68b552023-10-03 11:11:47 +010047 size_t attest_token_len, length;
AlexeiFedorovec35c542023-04-27 17:52:02 +010048 struct rec_attest_data *attest_data = rec->aux_data.attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +010049 uintptr_t cca_token_buf = rec->aux_data.cca_token_buf;
Soby Mathewb4c6df42022-11-09 11:13:29 +000050
51 /*
Soby Mathewb4c6df42022-11-09 11:13:29 +000052 * Translate realm granule IPA to PA. If returns with
53 * WALK_SUCCESS then the last level page table (llt),
54 * which holds the realm_att_token_buf mapping, is locked.
55 */
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010056 walk_status = realm_ipa_to_pa(rec, realm_att_token_ipa, &walk_res);
Soby Mathewb4c6df42022-11-09 11:13:29 +000057
58 /* Walk parameter validity was checked by RSI_ATTESTATION_TOKEN_INIT */
59 assert(walk_status != WALK_INVALID_PARAMS);
60
61 if (walk_status == WALK_FAIL) {
AlexeiFedorovd2e1bbd2023-04-18 15:18:39 +010062 if (walk_res.ripas_val == RIPAS_EMPTY) {
Soby Mathewb4c6df42022-11-09 11:13:29 +000063 res->smc_res.x[0] = RSI_ERROR_INPUT;
64 } else {
65 /*
AlexeiFedorov97844202023-04-27 15:17:35 +010066 * Translation failed, IPA is not mapped.
67 * Return to NS host to fix the issue.
Soby Mathewb4c6df42022-11-09 11:13:29 +000068 */
AlexeiFedorov97844202023-04-27 15:17:35 +010069 res->action = STAGE_2_TRANSLATION_FAULT;
70 res->rtt_level = walk_res.rtt_level;
Soby Mathewb4c6df42022-11-09 11:13:29 +000071 }
72 return;
73 }
74
Soby Mathew19eb4332023-11-20 14:03:23 +000075 /* If size of buffer is 0, then return early. */
AlexeiFedorovea68b552023-10-03 11:11:47 +010076 if (size == 0UL) {
Soby Mathew19eb4332023-11-20 14:03:23 +000077 res->smc_res.x[0] = RSI_INCOMPLETE;
78 goto out_unlock;
AlexeiFedorovea68b552023-10-03 11:11:47 +010079 }
80
Soby Mathewb4c6df42022-11-09 11:13:29 +000081 /* Map realm data granule to RMM address space */
82 gr = find_granule(walk_res.pa);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +000083 realm_att_token = (uintptr_t)buffer_granule_map(gr, SLOT_RSI_CALL);
AlexeiFedorovea68b552023-10-03 11:11:47 +010084 assert(realm_att_token != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +000085
Mate Toth-Pal4feff402024-08-30 10:53:32 +020086 if (attest_data->rmm_cca_token_copied_len == 0UL) {
AlexeiFedorovea68b552023-10-03 11:11:47 +010087 attest_token_len = attest_cca_token_create(
Soby Mathewf3622132024-07-19 07:31:40 +010088 &attest_data->token_sign_ctx,
AlexeiFedorovea68b552023-10-03 11:11:47 +010089 (void *)cca_token_buf,
90 REC_ATTEST_TOKEN_BUF_SIZE,
91 &attest_data->rmm_realm_token_buf,
92 attest_data->rmm_realm_token_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +000093
AlexeiFedorovea68b552023-10-03 11:11:47 +010094 if (attest_token_len == 0UL) {
95 res->smc_res.x[0] = RSI_ERROR_INPUT;
AlexeiFedorovea68b552023-10-03 11:11:47 +010096 goto out_unmap;
97 }
98
Mate Toth-Pal4feff402024-08-30 10:53:32 +020099 attest_data->rmm_cca_token_len = attest_token_len;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100100 } else {
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200101 attest_token_len = attest_data->rmm_cca_token_len;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100102 }
103
104 length = (size < attest_token_len) ? size : attest_token_len;
105
106 /* Copy attestation token */
107 (void)memcpy((void *)(realm_att_token + offset),
108 (void *)(cca_token_buf +
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200109 attest_data->rmm_cca_token_copied_len),
AlexeiFedorovea68b552023-10-03 11:11:47 +0100110 length);
111
112 attest_token_len -= length;
113
114 if (attest_token_len != 0UL) {
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200115 attest_data->rmm_cca_token_len = attest_token_len;
116 attest_data->rmm_cca_token_copied_len += length;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100117
118 res->smc_res.x[0] = RSI_INCOMPLETE;
119 } else {
AlexeiFedorovea68b552023-10-03 11:11:47 +0100120 res->smc_res.x[0] = RSI_SUCCESS;
121 }
122
123 res->smc_res.x[1] = length;
124
125out_unmap:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000126 /* Unmap realm granule */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100127 buffer_unmap((void *)realm_att_token);
Soby Mathew19eb4332023-11-20 14:03:23 +0000128out_unlock:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000129 /* Unlock last level page table (walk_res.g_llt) */
130 granule_unlock(walk_res.llt);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000131}
132
AlexeiFedorov97844202023-04-27 15:17:35 +0100133void handle_rsi_attest_token_init(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000134{
AlexeiFedorovea68b552023-10-03 11:11:47 +0100135 struct rd *rd;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100136 struct rec_attest_data *attest_data;
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200137 void *rpv_ptr;
138 size_t rpv_len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000139 int att_ret;
140
141 assert(rec != NULL);
142
AlexeiFedorovec35c542023-04-27 17:52:02 +0100143 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100144 res->action = UPDATE_REC_RETURN_TO_REALM;
145
Soby Mathewb4c6df42022-11-09 11:13:29 +0000146 /*
147 * Calling RSI_ATTESTATION_TOKEN_INIT any time aborts any ongoing
148 * operation.
Soby Mathewb4c6df42022-11-09 11:13:29 +0000149 */
Soby Mathewf3622132024-07-19 07:31:40 +0100150 att_ret = attest_token_ctx_init(&attest_data->token_sign_ctx,
151 rec->aux_data.attest_heap_buf,
152 REC_HEAP_SIZE);
153 if (att_ret != 0) {
154 /* There is no provision for this failure so panic */
155 panic();
Soby Mathewb4c6df42022-11-09 11:13:29 +0000156 }
157
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200158 /* Initialize length fields in attestation data */
Soby Mathewf3622132024-07-19 07:31:40 +0100159 attest_data->rmm_realm_token_len = 0;
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200160 attest_data->rmm_cca_token_copied_len = 0;
161 attest_data->rmm_cca_token_len = 0;
AlexeiFedorov2dcd79f2023-10-17 10:04:11 +0100162
Soby Mathewb4c6df42022-11-09 11:13:29 +0000163 /*
164 * rd lock is acquired so that measurement cannot be updated
165 * simultaneously by another rec
166 */
167 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000168 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100169 assert(rd != NULL);
170
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200171 get_rpv(rd, &rpv_ptr, &rpv_len);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000172 att_ret = attest_realm_token_create(rd->algorithm, rd->measurement,
173 MEASUREMENT_SLOT_NR,
Mate Toth-Pal071aa562023-07-04 09:09:26 +0200174 rpv_ptr,
175 rpv_len,
Mate Toth-Pal4feff402024-08-30 10:53:32 +0200176 (const void *)&rec->regs[1],
177 ATTEST_CHALLENGE_SIZE,
AlexeiFedorovec35c542023-04-27 17:52:02 +0100178 &attest_data->token_sign_ctx,
179 attest_data->rmm_realm_token_buf,
180 sizeof(attest_data->rmm_realm_token_buf));
AlexeiFedorovea68b552023-10-03 11:11:47 +0100181 buffer_unmap(rd);
182 granule_unlock(rec->realm_info.g_rd);
183
Soby Mathewb4c6df42022-11-09 11:13:29 +0000184 if (att_ret != 0) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100185 ERROR("FATAL_ERROR: Realm token creation failed\n");
Soby Mathewb4c6df42022-11-09 11:13:29 +0000186 panic();
187 }
188
AlexeiFedorovea68b552023-10-03 11:11:47 +0100189 res->smc_res.x[0] = RSI_SUCCESS;
AlexeiFedorov755a70b2023-10-12 12:31:45 +0100190 res->smc_res.x[1] = REC_ATTEST_TOKEN_BUF_SIZE;
AlexeiFedorov97844202023-04-27 15:17:35 +0100191}
192
193/*
194 * Return 'false' if no IRQ is pending,
195 * return 'true' if there is an IRQ pending, and need to return to Host.
196 */
197static bool check_pending_irq(void)
198{
199 return (read_isr_el1() != 0UL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000200}
201
Soby Mathewb4c6df42022-11-09 11:13:29 +0000202void handle_rsi_attest_token_continue(struct rec *rec,
AlexeiFedorov97844202023-04-27 15:17:35 +0100203 struct rmi_rec_exit *rec_exit,
204 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000205{
AlexeiFedorovec35c542023-04-27 17:52:02 +0100206 struct rec_attest_data *attest_data;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100207 unsigned long realm_buf_ipa, offset, size;
AlexeiFedorovec35c542023-04-27 17:52:02 +0100208
Soby Mathewb4c6df42022-11-09 11:13:29 +0000209 assert(rec != NULL);
AlexeiFedorov97844202023-04-27 15:17:35 +0100210 assert(rec_exit != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000211
AlexeiFedorovec35c542023-04-27 17:52:02 +0100212 attest_data = rec->aux_data.attest_data;
AlexeiFedorov97844202023-04-27 15:17:35 +0100213 res->action = UPDATE_REC_RETURN_TO_REALM;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000214
AlexeiFedorovea68b552023-10-03 11:11:47 +0100215 realm_buf_ipa = rec->regs[1];
216 offset = rec->regs[2];
217 size = rec->regs[3];
218
219 if (!GRANULE_ALIGNED(realm_buf_ipa) ||
220 (offset >= GRANULE_SIZE) ||
221 ((offset + size) > GRANULE_SIZE) ||
222 ((offset + size) < offset)) {
Soby Mathewb4c6df42022-11-09 11:13:29 +0000223 res->smc_res.x[0] = RSI_ERROR_INPUT;
224 return;
225 }
226
AlexeiFedorovea68b552023-10-03 11:11:47 +0100227 if (!addr_in_rec_par(rec, realm_buf_ipa)) {
228 res->smc_res.x[0] = RSI_ERROR_INPUT;
229 return;
230 }
AlexeiFedorov97844202023-04-27 15:17:35 +0100231
Soby Mathewf3622132024-07-19 07:31:40 +0100232 /* Sign the token */
233 while (attest_data->rmm_realm_token_len == 0U) {
234 enum attest_token_err_t ret;
AlexeiFedorovea68b552023-10-03 11:11:47 +0100235
Soby Mathewf3622132024-07-19 07:31:40 +0100236 ret = attest_realm_token_sign(&(attest_data->token_sign_ctx),
237 &(attest_data->rmm_realm_token_len));
238
239 if (ret == ATTEST_TOKEN_ERR_INVALID_STATE) {
240 /*
241 * Before this call the initial attestation token call
242 * (SMC_RSI_ATTEST_TOKEN_INIT) must have been executed
243 * successfully.
244 */
245 res->smc_res.x[0] = RSI_ERROR_STATE;
246 return;
247 } else if ((ret != ATTEST_TOKEN_ERR_COSE_SIGN_IN_PROGRESS) &&
248 (ret != ATTEST_TOKEN_ERR_SUCCESS)) {
249 /* Accessible only in case of failure during token signing */
250 ERROR("FATAL_ERROR: Realm token sign failed\n");
251 panic();
252 }
253
254 res->smc_res.x[0] = RSI_INCOMPLETE;
255
256 /*
257 * Return to RSI handler function after each iteration
258 * to check is there anything else to do (pending IRQ)
259 * or next signing iteration can be executed.
260 */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100261 if (check_pending_irq()) {
262 res->action = UPDATE_REC_EXIT_TO_HOST;
263 rec_exit->exit_reason = RMI_EXIT_IRQ;
264 return;
AlexeiFedorov97844202023-04-27 15:17:35 +0100265 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000266 }
AlexeiFedorovea68b552023-10-03 11:11:47 +0100267
AlexeiFedorovea68b552023-10-03 11:11:47 +0100268 attest_token_continue_write_state(rec, res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000269}
270
AlexeiFedorov97844202023-04-27 15:17:35 +0100271void handle_rsi_measurement_extend(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000272{
273 struct granule *g_rd;
274 struct rd *rd;
275 unsigned long index;
276 unsigned long rd_addr;
277 size_t size;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000278 void *extend_measurement;
279 unsigned char *current_measurement;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000280
AlexeiFedorov97844202023-04-27 15:17:35 +0100281 assert(rec != NULL);
282
283 res->action = UPDATE_REC_RETURN_TO_REALM;
284
Soby Mathewb4c6df42022-11-09 11:13:29 +0000285 /*
286 * rd lock is acquired so that measurement cannot be updated
287 * simultaneously by another rec
288 */
289 rd_addr = granule_addr(rec->realm_info.g_rd);
290 g_rd = find_lock_granule(rd_addr, GRANULE_STATE_RD);
291
292 assert(g_rd != NULL);
293
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000294 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100295 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000296
297 /*
298 * X1: index
299 * X2: size
300 * X3-X10: measurement value
301 */
302 index = rec->regs[1];
303
304 if ((index == RIM_MEASUREMENT_SLOT) ||
305 (index >= MEASUREMENT_SLOT_NR)) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100306 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000307 goto out_unmap_rd;
308 }
309
310 size = rec->regs[2];
311
312 if (size > MAX_EXTENDED_SIZE) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100313 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000314 goto out_unmap_rd;
315 }
316
317 extend_measurement = &rec->regs[3];
318 current_measurement = rd->measurement[index];
319
320 measurement_extend(rd->algorithm,
321 current_measurement,
322 extend_measurement,
323 size,
324 current_measurement);
325
AlexeiFedorov97844202023-04-27 15:17:35 +0100326 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000327
328out_unmap_rd:
329 buffer_unmap(rd);
330 granule_unlock(g_rd);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000331}
332
AlexeiFedorov97844202023-04-27 15:17:35 +0100333void handle_rsi_measurement_read(struct rec *rec, struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000334{
335 struct rd *rd;
336 unsigned long idx;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100337 unsigned int i, cnt;
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200338 unsigned long *measurement_value_part;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000339
340 assert(rec != NULL);
341
AlexeiFedorov97844202023-04-27 15:17:35 +0100342 res->action = UPDATE_REC_RETURN_TO_REALM;
343
Soby Mathewb4c6df42022-11-09 11:13:29 +0000344 /* X1: Index */
345 idx = rec->regs[1];
346
347 if (idx >= MEASUREMENT_SLOT_NR) {
AlexeiFedorov97844202023-04-27 15:17:35 +0100348 res->smc_res.x[0] = RSI_ERROR_INPUT;
349 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000350 }
351
352 /*
353 * rd lock is acquired so that measurement cannot be updated
354 * simultaneously by another rec
355 */
356 granule_lock(rec->realm_info.g_rd, GRANULE_STATE_RD);
Javier Almansa Sobrino2f717dd2024-02-12 20:49:46 +0000357 rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
AlexeiFedorov9a9062c2023-08-21 15:41:48 +0100358 assert(rd != NULL);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000359
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100360 /* Number of 8-bytes words in measurement */
AlexeiFedorov4faab852023-08-30 15:06:49 +0100361 cnt = (unsigned int)(measurement_get_size(rd->algorithm) /
362 sizeof(unsigned long));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000363
AlexeiFedorovea68b552023-10-03 11:11:47 +0100364 assert(cnt >= (SMC_RESULT_REGS - 1U));
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200365 assert(cnt < ARRAY_LEN(rec->regs));
366
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100367 /* Copy the part of the measurement to res->smc_res.x[] */
AlexeiFedorovea68b552023-10-03 11:11:47 +0100368 for (i = 0U; i < (SMC_RESULT_REGS - 1U); i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200369 measurement_value_part = (unsigned long *)
370 &(rd->measurement[idx][i * sizeof(unsigned long)]);
371 res->smc_res.x[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100372 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000373
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100374 /* Copy the rest of the measurement to the rec->regs[] */
375 for (; i < cnt; i++) {
Mate Toth-Pal59b52d02023-08-18 14:14:19 +0200376 measurement_value_part = (unsigned long *)
377 &(rd->measurement[idx][i * sizeof(unsigned long)]);
378 rec->regs[i + 1U] = *measurement_value_part;
AlexeiFedorovefe2aec2023-06-08 16:17:00 +0100379 }
380
381 /* Zero-initialize unused area */
382 for (; i < MAX_MEASUREMENT_WORDS; i++) {
383 rec->regs[i + 1U] = 0UL;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000384 }
385
386 buffer_unmap(rd);
387 granule_unlock(rec->realm_info.g_rd);
388
AlexeiFedorov97844202023-04-27 15:17:35 +0100389 res->smc_res.x[0] = RSI_SUCCESS;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000390}