blob: 2556c11aa767bd12ef484b8d3f22aba5fbe6a7bb [file] [log] [blame]
nabkah01002e5692022-10-10 12:36:46 +01001/*
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +01002 * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
nabkah01002e5692022-10-10 12:36:46 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <stdio.h>
9
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010010#include <arch_features.h>
nabkah01002e5692022-10-10 12:36:46 +010011#include <debug.h>
Shruti Gupta369955a2023-04-19 18:05:56 +010012#include <fpu.h>
nabkah01002e5692022-10-10 12:36:46 +010013#include <host_realm_helper.h>
14#include <host_shared_data.h>
Shruti Gupta9d0cfe82023-04-17 10:57:26 +010015#include <pauth.h>
nabkah01002e5692022-10-10 12:36:46 +010016#include "realm_def.h"
Shruti Gupta91105082024-11-27 05:29:55 +000017#include <realm_helpers.h>
18#include <realm_psi.h>
nabkah01002e5692022-10-10 12:36:46 +010019#include <realm_rsi.h>
AlexeiFedorov2f30f102023-03-13 19:37:46 +000020#include <realm_tests.h>
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010021#include <serror.h>
Shruti Guptab027f572024-01-02 22:00:29 +000022#include <sync.h>
nabkah01002e5692022-10-10 12:36:46 +010023#include <tftf_lib.h>
24
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010025static fpu_state_t rl_fpu_state_write;
26static fpu_state_t rl_fpu_state_read;
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +010027
nabkah01002e5692022-10-10 12:36:46 +010028/*
AlexeiFedorov2f30f102023-03-13 19:37:46 +000029 * This function reads sleep time in ms from shared buffer and spins PE
30 * in a loop for that time period.
nabkah01002e5692022-10-10 12:36:46 +010031 */
32static void realm_sleep_cmd(void)
33{
Shruti Gupta52b5f022023-10-12 22:02:29 +010034 uint64_t sleep = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
nabkah01002e5692022-10-10 12:36:46 +010035
Shruti Guptaa276b202023-12-18 10:07:43 +000036 realm_printf("going to sleep for %llums\n", sleep);
nabkah01002e5692022-10-10 12:36:46 +010037 waitms(sleep);
38}
39
Shruti Gupta6bb95102023-10-02 13:21:37 +010040static void realm_loop_cmd(void)
41{
42 while (true) {
43 waitms(500);
44 }
45}
46
nabkah01002e5692022-10-10 12:36:46 +010047/*
48 * This function requests RSI/ABI version from RMM.
49 */
Shruti Gupta40de8ec2023-10-12 21:45:12 +010050static bool realm_get_rsi_version(void)
nabkah01002e5692022-10-10 12:36:46 +010051{
Shruti Gupta40de8ec2023-10-12 21:45:12 +010052 u_register_t version = 0U;
nabkah01002e5692022-10-10 12:36:46 +010053
Shruti Gupta40de8ec2023-10-12 21:45:12 +010054 version = rsi_get_version(RSI_ABI_VERSION_VAL);
nabkah01002e5692022-10-10 12:36:46 +010055 if (version == (u_register_t)SMC_UNKNOWN) {
Shruti Gupta40de8ec2023-10-12 21:45:12 +010056 realm_printf("SMC_RSI_ABI_VERSION failed\n");
57 return false;
nabkah01002e5692022-10-10 12:36:46 +010058 }
59
Shruti Gupta40de8ec2023-10-12 21:45:12 +010060 realm_printf("RSI ABI version %u.%u (expected: %u.%u)\n",
nabkah01002e5692022-10-10 12:36:46 +010061 RSI_ABI_VERSION_GET_MAJOR(version),
62 RSI_ABI_VERSION_GET_MINOR(version),
Shruti Gupta40de8ec2023-10-12 21:45:12 +010063 RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION_VAL),
64 RSI_ABI_VERSION_GET_MINOR(RSI_ABI_VERSION_VAL));
65 return true;
nabkah01002e5692022-10-10 12:36:46 +010066}
67
Shruti Guptabb772192023-10-09 16:08:28 +010068bool test_realm_set_ripas(void)
69{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010070 u_register_t ret, base, new_base, top, new_top;
Shruti Guptabb772192023-10-09 16:08:28 +010071 rsi_ripas_respose_type response;
72 rsi_ripas_type ripas;
73
74 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
75 top = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010076 realm_printf("base=0x%lx top=0x%lx\n", base, top);
77 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
Shruti Guptabb772192023-10-09 16:08:28 +010078 if (ripas != RSI_EMPTY) {
79 return false;
80 }
81
82 ret = rsi_ipa_state_set(base, top, RSI_RAM,
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010083 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
84 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010085 return false;
86 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010087
Shruti Guptabb772192023-10-09 16:08:28 +010088 while (new_base < top) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010089 realm_printf("new_base=0x%lx top=0x%lx\n", new_base, top);
Shruti Guptabb772192023-10-09 16:08:28 +010090 ret = rsi_ipa_state_set(new_base, top, RSI_RAM,
91 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010092 if ((ret != RSI_SUCCESS) || (response != RSI_ACCEPT)) {
Shruti Guptabb772192023-10-09 16:08:28 +010093 realm_printf("rsi_ipa_state_set failed\n");
94 return false;
95 }
96 }
97
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +010098 /* Verify that RIAS has changed for range base-top */
99 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
100 if ((ret != RSI_SUCCESS) || (ripas != RSI_RAM) || (new_top != top)) {
101 realm_printf("rsi_ipa_state_get failed base=0x%lx top=0x%lx",
102 "new_top=0x%lx ripas=%u ret=0x%lx\n",
103 base, top, ripas);
104 return false;
Shruti Guptabb772192023-10-09 16:08:28 +0100105 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100106
Shruti Guptabb772192023-10-09 16:08:28 +0100107 return true;
108}
109
Shruti Guptafef86212023-10-17 12:15:38 +0100110bool test_realm_reject_set_ripas(void)
111{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100112 u_register_t ret, base, top, new_base, new_top;
Shruti Guptafef86212023-10-17 12:15:38 +0100113 rsi_ripas_respose_type response;
114 rsi_ripas_type ripas;
115
116 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100117 top = base + PAGE_SIZE;
118 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
119 if ((ret != RSI_SUCCESS) || (ripas != RSI_EMPTY)) {
120 realm_printf("Wrong initial ripas=%u\n", ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100121 return false;
122 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100123 ret = rsi_ipa_state_set(base, top, RSI_RAM,
124 RSI_NO_CHANGE_DESTROYED, &new_base, &response);
125 if ((ret == RSI_SUCCESS) && (response == RSI_REJECT)) {
126 realm_printf("rsi_ipa_state_set passed response=%u\n", response);
127 ret = rsi_ipa_state_get(base, top, &new_top, &ripas);
128 if ((ret == RSI_SUCCESS) && (ripas == RSI_EMPTY) &&
129 (new_top == top)) {
Shruti Guptafef86212023-10-17 12:15:38 +0100130 return true;
131 } else {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100132 realm_printf("rsi_ipa_state_get failed top=0x%lx",
133 "new_top=0x%lx ripas=%u ret=0x%lx\n",
134 ripas);
Shruti Guptafef86212023-10-17 12:15:38 +0100135 return false;
136 }
137 }
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100138 realm_printf("rsi_ipa_state_set failed ret=0x%lx response=%u\n",
139 ret, response);
Shruti Guptafef86212023-10-17 12:15:38 +0100140 return false;
141}
142
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000143bool test_realm_dit_check_cmd(void)
144{
145 if (is_armv8_4_dit_present()) {
146 write_dit(DIT_BIT);
147 realm_printf("Testing DIT=0x%lx\n", read_dit());
148 /* Test if DIT is preserved after HOST_CALL */
149 if (read_dit() == DIT_BIT) {
150 return true;
151 }
152 }
153 return false;
154}
155
Shruti Guptae68494e2023-11-06 11:04:57 +0000156static bool test_realm_instr_fetch_cmd(void)
157{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100158 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000159 void (*func_ptr)(void);
160 rsi_ripas_type ripas;
161
162 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100163 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
164 realm_printf("Initial ripas=%u\n", ripas);
165 /* Causes instruction abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000166 realm_printf("Generate Instruction Abort\n");
167 func_ptr = (void (*)(void))base;
168 func_ptr();
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100169 /* Should not return */
Shruti Guptae68494e2023-11-06 11:04:57 +0000170 return false;
171}
172
173static bool test_realm_data_access_cmd(void)
174{
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100175 u_register_t base, new_top;
Shruti Guptae68494e2023-11-06 11:04:57 +0000176 rsi_ripas_type ripas;
Shruti Guptae68494e2023-11-06 11:04:57 +0000177 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100178 rsi_ipa_state_get(base, base + PAGE_SIZE, &new_top, &ripas);
179 realm_printf("Initial ripas=%u\n", ripas);
180 /* Causes data abort */
Shruti Guptae68494e2023-11-06 11:04:57 +0000181 realm_printf("Generate Data Abort\n");
182 *((volatile uint64_t *)base);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100183
Shruti Guptae68494e2023-11-06 11:04:57 +0000184 return false;
185}
186
Shruti Guptab027f572024-01-02 22:00:29 +0000187static bool realm_exception_handler(void)
188{
Shruti Gupta91105082024-11-27 05:29:55 +0000189 u_register_t base, far, esr, elr;
Shruti Guptab027f572024-01-02 22:00:29 +0000190
191 base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
192 far = read_far_el1();
193 esr = read_esr_el1();
Shruti Gupta91105082024-11-27 05:29:55 +0000194 elr = read_elr_el1();
Shruti Guptab027f572024-01-02 22:00:29 +0000195
196 if (far == base) {
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100197 /* Return ESR to Host */
Shruti Guptab027f572024-01-02 22:00:29 +0000198 realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
199 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
200 }
Shruti Gupta91105082024-11-27 05:29:55 +0000201 realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx ELR=0x%lx\n",
202 far, esr, elr);
Shruti Guptab027f572024-01-02 22:00:29 +0000203 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
204
AlexeiFedorov9a60ecb2024-08-06 16:39:00 +0100205 /* Should not return */
Shruti Guptab027f572024-01-02 22:00:29 +0000206 return false;
207}
208
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000209static bool realm_serror_handler_doublefault(bool *incr_elr_elx)
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100210{
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000211 *incr_elr_elx = false;
212
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100213 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) != 0UL) {
214 /* The serror exception should have been routed here */
Manish V Badarkhe46d02282024-11-18 16:58:37 +0000215 *incr_elr_elx = true;
216
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100217 return true;
218 }
219
220 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
221
222 /* Should have never get here */
223 return false;
224}
225
226static bool realm_sync_handler_doublefault(void)
227{
228 if ((read_sctlr2_el1() & SCTLR2_EASE_BIT) == 0UL) {
229 /* The sync exception should have been routed here */
230 return true;
231 }
232
233 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
234
235 /* Should have never get here */
236 return false;
237}
238
239static void test_realm_feat_doublefault2(void)
240{
241 u_register_t ease_bit = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
242
243 unregister_custom_sync_exception_handler();
244 register_custom_sync_exception_handler(realm_sync_handler_doublefault);
245 register_custom_serror_handler(realm_serror_handler_doublefault);
246
247 if (ease_bit != 0UL) {
248 write_sctlr2_el1(read_sctlr2_el1() | SCTLR2_EASE_BIT);
249 } else {
250 write_sctlr2_el1(read_sctlr2_el1() & ~SCTLR2_EASE_BIT);
251 }
252
253 (void)test_realm_data_access_cmd();
254}
255
nabkah01002e5692022-10-10 12:36:46 +0100256/*
257 * This is the entry function for Realm payload, it first requests the shared buffer
258 * IPA address from Host using HOST_CALL/RSI, it reads the command to be executed,
259 * performs the request, and returns to Host with the execution state SUCCESS/FAILED
260 *
261 * Host in NS world requests Realm to execute certain operations using command
262 * depending on the test case the Host wants to perform.
263 */
264void realm_payload_main(void)
265{
nabkah01002e5692022-10-10 12:36:46 +0100266 bool test_succeed = false;
267
Shruti Guptab027f572024-01-02 22:00:29 +0000268 register_custom_sync_exception_handler(realm_exception_handler);
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100269
270 /* No serror handler registered by default */
271 unregister_custom_serror_handler();
272
Shruti Gupta69cae792024-11-27 04:30:00 +0000273 realm_set_shared_structure(realm_get_ns_buffer());
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100274
Shruti Gupta550e3e82023-08-16 13:20:11 +0100275 if (realm_get_my_shared_structure() != NULL) {
276 uint8_t cmd = realm_shared_data_get_my_realm_cmd();
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000277
nabkah01002e5692022-10-10 12:36:46 +0100278 switch (cmd) {
279 case REALM_SLEEP_CMD:
280 realm_sleep_cmd();
281 test_succeed = true;
282 break;
Shruti Gupta6bb95102023-10-02 13:21:37 +0100283 case REALM_LOOP_CMD:
284 realm_loop_cmd();
285 test_succeed = true;
286 break;
Shruti Gupta24597d12023-10-02 10:40:19 +0100287 case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
288 test_succeed = test_realm_multiple_rec_psci_denied_cmd();
Shruti Guptae68494e2023-11-06 11:04:57 +0000289 break;
Shruti Guptaaffbae82023-08-22 12:51:11 +0100290 case REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD:
291 test_succeed = test_realm_multiple_rec_multiple_cpu_cmd();
Shruti Gupta24597d12023-10-02 10:40:19 +0100292 break;
Javier Almansa Sobrino7c78f7b2024-10-25 11:44:32 +0100293 case REALM_FEAT_DOUBLEFAULT2_TEST:
294 test_realm_feat_doublefault2();
295 test_succeed = true;
296 break;
Shruti Guptae68494e2023-11-06 11:04:57 +0000297 case REALM_INSTR_FETCH_CMD:
298 test_succeed = test_realm_instr_fetch_cmd();
299 break;
300 case REALM_DATA_ACCESS_CMD:
301 test_succeed = test_realm_data_access_cmd();
302 break;
Shruti Gupta9d0cfe82023-04-17 10:57:26 +0100303 case REALM_PAUTH_SET_CMD:
304 test_succeed = test_realm_pauth_set_cmd();
305 break;
306 case REALM_PAUTH_CHECK_CMD:
307 test_succeed = test_realm_pauth_check_cmd();
308 break;
309 case REALM_PAUTH_FAULT:
310 test_succeed = test_realm_pauth_fault();
311 break;
Shruti Gupta2a5abad2024-01-17 13:48:44 +0000312 case REALM_DIT_CHECK_CMD:
313 test_succeed = test_realm_dit_check_cmd();
314 break;
nabkah01002e5692022-10-10 12:36:46 +0100315 case REALM_GET_RSI_VERSION:
Shruti Gupta40de8ec2023-10-12 21:45:12 +0100316 test_succeed = realm_get_rsi_version();
nabkah01002e5692022-10-10 12:36:46 +0100317 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000318 case REALM_PMU_CYCLE:
319 test_succeed = test_pmuv3_cycle_works_realm();
320 break;
Shruti Guptab1b37922024-01-13 21:49:04 +0000321 case REALM_PMU_COUNTER:
322 test_succeed = test_pmuv3_counter();
323 break;
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000324 case REALM_PMU_EVENT:
325 test_succeed = test_pmuv3_event_works_realm();
326 break;
327 case REALM_PMU_PRESERVE:
328 test_succeed = test_pmuv3_rmm_preserves();
329 break;
330 case REALM_PMU_INTERRUPT:
331 test_succeed = test_pmuv3_overflow_interrupt();
332 break;
Shruti Gupta369955a2023-04-19 18:05:56 +0100333 case REALM_REQ_FPU_FILL_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100334 fpu_state_write_rand(&rl_fpu_state_write);
Shruti Gupta369955a2023-04-19 18:05:56 +0100335 test_succeed = true;
336 break;
337 case REALM_REQ_FPU_CMP_CMD:
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100338 fpu_state_read(&rl_fpu_state_read);
339 test_succeed = !fpu_state_compare(&rl_fpu_state_write,
340 &rl_fpu_state_read);
Arunachalam Ganapathy9af432e2023-06-02 17:18:23 +0100341 break;
Shruti Guptafef86212023-10-17 12:15:38 +0100342 case REALM_REJECT_SET_RIPAS_CMD:
343 test_succeed = test_realm_reject_set_ripas();
344 break;
Shruti Guptabb772192023-10-09 16:08:28 +0100345 case REALM_SET_RIPAS_CMD:
346 test_succeed = test_realm_set_ripas();
347 break;
Arunachalam Ganapathy0bbdc2d2023-04-05 15:30:18 +0100348 case REALM_SVE_RDVL:
349 test_succeed = test_realm_sve_rdvl();
350 break;
351 case REALM_SVE_ID_REGISTERS:
352 test_succeed = test_realm_sve_read_id_registers();
353 break;
354 case REALM_SVE_PROBE_VL:
355 test_succeed = test_realm_sve_probe_vl();
Shruti Gupta369955a2023-04-19 18:05:56 +0100356 break;
Arunachalam Ganapathyc1136a82023-04-12 15:24:44 +0100357 case REALM_SVE_OPS:
358 test_succeed = test_realm_sve_ops();
359 break;
Arunachalam Ganapathy5270d012023-04-19 14:53:42 +0100360 case REALM_SVE_FILL_REGS:
361 test_succeed = test_realm_sve_fill_regs();
362 break;
Arunachalam Ganapathyf3697172023-09-04 15:04:46 +0100363 case REALM_SVE_CMP_REGS:
364 test_succeed = test_realm_sve_cmp_regs();
365 break;
Arunachalam Ganapathy73949a22023-06-05 12:01:05 +0100366 case REALM_SVE_UNDEF_ABORT:
367 test_succeed = test_realm_sve_undef_abort();
368 break;
Arunachalam Ganapathy1768e592023-05-23 13:28:38 +0100369 case REALM_SME_ID_REGISTERS:
370 test_succeed = test_realm_sme_read_id_registers();
371 break;
372 case REALM_SME_UNDEF_ABORT:
373 test_succeed = test_realm_sme_undef_abort();
374 break;
Juan Pablo Conde88ffad22024-10-11 21:22:29 -0500375 case REALM_ATTESTATION:
376 test_succeed = test_realm_attestation();
377 break;
378 case REALM_ATTESTATION_FAULT:
379 test_succeed = test_realm_attestation_fault();
380 break;
nabkah01002e5692022-10-10 12:36:46 +0100381 default:
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000382 realm_printf("%s() invalid cmd %u\n", __func__, cmd);
nabkah01002e5692022-10-10 12:36:46 +0100383 break;
384 }
385 }
386
387 if (test_succeed) {
Shruti Gupta91105082024-11-27 05:29:55 +0000388 if (realm_is_plane0()) {
389 rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
390 } else {
391 psi_exit_to_plane0(PSI_CALL_EXIT_SUCCESS_CMD,
392 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
393 }
nabkah01002e5692022-10-10 12:36:46 +0100394 } else {
Shruti Gupta91105082024-11-27 05:29:55 +0000395 if (realm_is_plane0()) {
396 rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
397 } else {
398 psi_exit_to_plane0(PSI_CALL_EXIT_FAILED_CMD,
399 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
400 }
nabkah01002e5692022-10-10 12:36:46 +0100401 }
402}