blob: 5c173c57cbf27a31b903646f1288d2991c346c8c [file] [log] [blame]
Manish Pandey5f513d62022-01-17 11:05:53 +00001/*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Olivier Deprez82bbc572022-01-11 11:50:36 +01007#include <plat/common/platform.h>
8
Manish Pandey5f513d62022-01-17 11:05:53 +00009#include <arch.h>
10#include <arch_helpers.h>
11#include <arch_features.h>
12#include <debug.h>
13#ifdef __aarch64__
Daniel Boulby82bf3392023-07-28 18:32:27 +010014#include <spm_test_helpers.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000015#include <sync.h>
16#endif
nabkah01002e5692022-10-10 12:36:46 +010017#include <host_realm_helper.h>
Olivier Deprez82bbc572022-01-11 11:50:36 +010018#include <lib/aarch64/arch_features.h>
nabkah01002e5692022-10-10 12:36:46 +010019#include <test_helpers.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000020#include <tftf_lib.h>
Manish Pandey368054b2022-03-15 13:24:59 +000021#include <xlat_tables_v2.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000022#include <platform_def.h>
nabkah0146b418d2022-02-16 17:01:54 +000023#include <cactus_test_cmds.h>
24#include <ffa_endpoints.h>
25
Manish Pandey5f513d62022-01-17 11:05:53 +000026/*
27 * Using "__aarch64__" here looks weird but its unavoidable because of following reason
28 * This test is part of standard test which runs on all platforms but pre-requisite
29 * to run this test (custom sync exception handler) is only implemented for aarch64.
30 * TODO: Write a framework so that tests kept in standard list can be selectively
31 * run on a given architecture
32 */
33#ifdef __aarch64__
34
nabkah0146b418d2022-02-16 17:01:54 +000035#define SENDER HYP_ID
36#define RECEIVER SP_ID(1)
37
Manish Pandey5f513d62022-01-17 11:05:53 +000038static volatile bool sync_exception_triggered;
39static volatile bool data_abort_triggered;
nabkah0146b418d2022-02-16 17:01:54 +000040static const struct ffa_uuid expected_sp_uuids[] = {
41 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
42};
Manish Pandey5f513d62022-01-17 11:05:53 +000043
Olivier Deprez82bbc572022-01-11 11:50:36 +010044static __aligned(PAGE_SIZE) uint64_t share_page[PAGE_SIZE / sizeof(uint64_t)];
45
Manish Pandey5f513d62022-01-17 11:05:53 +000046static bool data_abort_handler(void)
47{
48 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
49 unsigned int rme_supported = get_armv9_2_feat_rme_support();
50
51 sync_exception_triggered = true;
52
53 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
54
55 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
56 if (rme_supported == 0) {
57 /* Synchronous external data abort triggered by trustzone controller */
58 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
59 VERBOSE("%s TZC Data Abort caught\n", __func__);
60 data_abort_triggered = true;
61 return true;
62 }
63 } else {
64 /* Synchronous data abort triggered by Granule protection */
65 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
66 VERBOSE("%s GPF Data Abort caught\n", __func__);
67 data_abort_triggered = true;
68 return true;
69 }
70 }
71 }
72
73 return false;
74}
75
nabkah01bf00f8d2022-03-22 12:37:19 +000076test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +000077{
78 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
79
Manish Pandey5f513d62022-01-17 11:05:53 +000080 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
81
Manish Pandey368054b2022-03-15 13:24:59 +000082 sync_exception_triggered = false;
Manish Pandey5f513d62022-01-17 11:05:53 +000083 data_abort_triggered = false;
Manish Pandey368054b2022-03-15 13:24:59 +000084
85 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
86 MT_MEMORY | MT_RW | MT_NS);
87 if (rc != 0) {
88 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
89 return TEST_RESULT_FAIL;
90 }
91
Manish Pandey5f513d62022-01-17 11:05:53 +000092 register_custom_sync_exception_handler(data_abort_handler);
Manish Pandey5f513d62022-01-17 11:05:53 +000093 *((volatile uint64_t *)test_address);
Manish Pandey5f513d62022-01-17 11:05:53 +000094 unregister_custom_sync_exception_handler();
95
Manish Pandey368054b2022-03-15 13:24:59 +000096 rc = mmap_remove_dynamic_region(test_address, PAGE_SIZE);
97 if (rc != 0) {
98 tftf_testcase_printf("%d: mmap_remove_dynamic_region() = %d\n", __LINE__, rc);
99 return TEST_RESULT_FAIL;
100 }
101
Manish Pandey5f513d62022-01-17 11:05:53 +0000102 if (sync_exception_triggered == false) {
103 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
104 return TEST_RESULT_SKIPPED;
105 }
106
107 if (data_abort_triggered == false) {
108 tftf_testcase_printf("Sync exception is not data abort\n");
109 return TEST_RESULT_FAIL;
110 }
111
112 return TEST_RESULT_SUCCESS;
113}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100114
115/**
116 * @Test_Aim@ Check a realm region cannot be accessed from normal world.
117 *
118 * This test delegates a TFTF allocated buffer to Realm. It then attempts
119 * a read access to the region from normal world. This results in the PE
120 * triggering a GPF caught by a custom synchronous abort handler.
121 *
122 */
123test_result_t rl_memory_cannot_be_accessed_in_ns(void)
124{
125 test_result_t result = TEST_RESULT_FAIL;
126 u_register_t retmm;
127
128 if (get_armv9_2_feat_rme_support() == 0U) {
129 return TEST_RESULT_SKIPPED;
130 }
131
132 sync_exception_triggered = false;
133 data_abort_triggered = false;
134 register_custom_sync_exception_handler(data_abort_handler);
135
136 /* First read access to the test region must not fail. */
137 *((volatile uint64_t *)share_page);
138
139 if ((sync_exception_triggered != false) ||
140 (data_abort_triggered != false)) {
141 goto out_unregister;
142 }
143
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000144 host_rmi_init_cmp_result();
AlexeiFedorov380b2af2022-11-23 17:31:27 +0000145
Olivier Deprez82bbc572022-01-11 11:50:36 +0100146 /* Delegate the shared page to Realm. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000147 retmm = host_rmi_granule_delegate((u_register_t)&share_page);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100148 if (retmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000149 ERROR("%s() failed\n", "host_rmi_granule_delegate");
Olivier Deprez82bbc572022-01-11 11:50:36 +0100150 goto out_unregister;
151 }
152
153 /* This access shall trigger a GPF. */
154 *((volatile uint64_t *)share_page);
155
156 if ((sync_exception_triggered != true) ||
157 (data_abort_triggered != true)) {
158 goto out_undelegate;
159 }
160
AlexeiFedorov380b2af2022-11-23 17:31:27 +0000161 result = host_cmp_result();
Olivier Deprez82bbc572022-01-11 11:50:36 +0100162
163out_undelegate:
164 /* Undelegate the shared page. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000165 retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100166 if (retmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000167 ERROR("Granule undelegate failed, ret=0x%lx\n", retmm);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100168 }
169
170out_unregister:
171 unregister_custom_sync_exception_handler();
172
173 return result;
174}
175
nabkah01bf00f8d2022-03-22 12:37:19 +0000176/**
177 * @Test_Aim@ Check a secure region cannot be accessed from normal world.
178 *
179 * Following test intends to run on RME enabled platforms when EL3
180 * is Root world. In a non RME platform, EL3 is secure.
181 * Access to secure memory from NS world is already covered
182 * by el3_memory_cannot_be_accessed_in_ns.
183 */
184test_result_t s_memory_cannot_be_accessed_in_ns(void)
185{
186 const uintptr_t test_address = SECURE_MEMORY_ACCESS_ADDR;
187
188 /* skipp non RME platforms */
189 if (get_armv9_2_feat_rme_support() == 0U) {
190 return TEST_RESULT_SKIPPED;
191 }
192
193 VERBOSE("Attempt to access secure memory (0x%lx)\n", test_address);
194
195 data_abort_triggered = false;
196 sync_exception_triggered = false;
197 register_custom_sync_exception_handler(data_abort_handler);
198 dsbsy();
199
200 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
201 MT_MEMORY | MT_RW | MT_NS);
202
203 if (rc != 0) {
204 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
205 return TEST_RESULT_FAIL;
206 }
207
208 *((volatile uint64_t *)test_address);
209
210 mmap_remove_dynamic_region(test_address, PAGE_SIZE);
211
212 dsbsy();
213 unregister_custom_sync_exception_handler();
214
215 if (sync_exception_triggered == false) {
216 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
217 return TEST_RESULT_SKIPPED;
218 }
219
220 if (data_abort_triggered == false) {
221 tftf_testcase_printf("Sync exception is not data abort\n");
222 return TEST_RESULT_FAIL;
223 }
224
225 return TEST_RESULT_SUCCESS;
226}
227
nabkah01905b2c72022-02-10 10:46:32 +0000228static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
229{
230 u_register_t retrmm;
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000231 test_result_t result = TEST_RESULT_FAIL;
nabkah01905b2c72022-02-10 10:46:32 +0000232 static char rd[GRANULE_SIZE] __aligned(GRANULE_SIZE);
233
Arunachalam Ganapathy4b221112023-04-05 14:19:03 +0100234 SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
nabkah01905b2c72022-02-10 10:46:32 +0000235
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000236 retrmm = host_rmi_granule_delegate((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000237 if (retrmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000238 ERROR("%s() failed, ret=0x%lx\n", "host_rmi_granule_delegate",
239 retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000240 return TEST_RESULT_FAIL;
241 }
242
243 /* Create a realm using a parameter in a secure physical address space should fail. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000244 retrmm = host_rmi_realm_create((u_register_t)&rd[0], params);
nabkah01905b2c72022-02-10 10:46:32 +0000245 if (retrmm == 0UL) {
246 ERROR("Realm create operation should fail, %lx\n", retrmm);
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000247 retrmm = host_rmi_realm_destroy((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000248 if (retrmm != 0UL) {
249 ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000250 }
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000251 } else if (retrmm != RMI_ERROR_INPUT) {
252 ERROR("Realm create operation should fail with code:%d retrmm:%ld\n",
253 RMI_ERROR_INPUT, retrmm);
254 } else {
255 result = TEST_RESULT_SUCCESS;
nabkah01905b2c72022-02-10 10:46:32 +0000256 }
257
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000258 retrmm = host_rmi_granule_undelegate((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000259 if (retrmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000260 INFO("Undelegate operation returns 0x%lx\n", retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000261 return TEST_RESULT_FAIL;
262 }
263
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000264 if (result == TEST_RESULT_SUCCESS) {
265 return host_cmp_result();
266 }
267
268 return TEST_RESULT_FAIL;
nabkah01905b2c72022-02-10 10:46:32 +0000269}
270
nabkah0146b418d2022-02-16 17:01:54 +0000271/**
272 * @Test_Aim@ Check a root region cannot be accessed from a secure partition.
273 *
274 * This change adds TFTF and cactus test to permit checking a root region
275 * cannot be accessed from secure world.
276 * A hardcoded address marked Root in the GPT is shared to a secure
277 * partition. The SP retrieves the region from the SPM, maps it and
278 * attempts a read access to the region. It is expected to trigger a GPF
279 * data abort on the PE caught by a custom exception handler.
280 *
281 */
282test_result_t rt_memory_cannot_be_accessed_in_s(void)
283{
284 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
285 struct ffa_memory_region_constituent constituents[] = {
286 {
287 (void *)test_address, 1, 0
288 }
289 };
290 const uint32_t constituents_count = sizeof(constituents) /
291 sizeof(struct ffa_memory_region_constituent);
292 ffa_memory_handle_t handle;
293 struct mailbox_buffers mb;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100294 struct ffa_value ret;
nabkah0146b418d2022-02-16 17:01:54 +0000295
296 if (get_armv9_2_feat_rme_support() == 0U) {
297 return TEST_RESULT_SKIPPED;
298 }
299
Olivier Deprezfac8ed72022-12-20 11:09:43 +0100300 SKIP_TEST_IF_FFA_VERSION_LESS_THAN(1,1);
nabkah0146b418d2022-02-16 17:01:54 +0000301
Olivier Deprezfac8ed72022-12-20 11:09:43 +0100302 CHECK_SPMC_TESTING_SETUP(1, 1, expected_sp_uuids);
303
nabkah0146b418d2022-02-16 17:01:54 +0000304 GET_TFTF_MAILBOX(mb);
305
306 handle = memory_init_and_send((struct ffa_memory_region *)mb.send,
307 PAGE_SIZE, SENDER, RECEIVER,
308 constituents, constituents_count,
309 FFA_MEM_SHARE_SMC32, &ret);
310
311 if (handle == FFA_MEMORY_HANDLE_INVALID) {
312 return TEST_RESULT_FAIL;
313 }
314
315 VERBOSE("TFTF - Handle: %llx Address: %p\n",
316 handle, constituents[0].address);
317
318 /* Retrieve the shared page and attempt accessing it. */
319 ret = cactus_mem_send_cmd(SENDER, RECEIVER, FFA_MEM_SHARE_SMC32,
320 handle, 0, true, 1);
321
322 if (is_ffa_call_error(ffa_mem_reclaim(handle, 0))) {
323 ERROR("Memory reclaim failed!\n");
324 return TEST_RESULT_FAIL;
325 }
326
327 /*
328 * Expect success response with value 1 hinting an exception
329 * triggered while the SP accessed the region.
330 */
331 if (!(cactus_get_response(ret) == CACTUS_SUCCESS &&
332 cactus_error_code(ret) == 1)) {
333 ERROR("Exceptions test failed!\n");
334 return TEST_RESULT_FAIL;
335 }
336
337 return TEST_RESULT_SUCCESS;
338}
339
nabkah01905b2c72022-02-10 10:46:32 +0000340test_result_t s_memory_cannot_be_accessed_in_rl(void)
341{
342 u_register_t params = (u_register_t)SECURE_MEMORY_ACCESS_ADDR;
343 return memory_cannot_be_accessed_in_rl(params);
344}
345
nabkah01e7147862022-02-11 19:08:00 +0000346test_result_t rt_memory_cannot_be_accessed_in_rl(void)
347{
348 u_register_t params = (u_register_t)EL3_MEMORY_ACCESS_ADDR;
349 return memory_cannot_be_accessed_in_rl(params);
350}
351
Manish Pandey5f513d62022-01-17 11:05:53 +0000352#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100353
nabkah01bf00f8d2022-03-22 12:37:19 +0000354test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +0000355{
356 tftf_testcase_printf("Test not ported to AArch32\n");
357 return TEST_RESULT_SKIPPED;
358}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100359
360test_result_t rl_memory_cannot_be_accessed_in_ns(void)
361{
362 tftf_testcase_printf("Test not ported to AArch32\n");
363 return TEST_RESULT_SKIPPED;
364}
365
nabkah01bf00f8d2022-03-22 12:37:19 +0000366test_result_t s_memory_cannot_be_accessed_in_ns(void)
367{
368 tftf_testcase_printf("Test not ported to AArch32\n");
369 return TEST_RESULT_SKIPPED;
370}
nabkah01905b2c72022-02-10 10:46:32 +0000371
372test_result_t s_memory_cannot_be_accessed_in_rl(void)
373{
374 tftf_testcase_printf("Test not ported to AArch32\n");
375 return TEST_RESULT_SKIPPED;
376}
377
nabkah01e7147862022-02-11 19:08:00 +0000378test_result_t rt_memory_cannot_be_accessed_in_rl(void)
379{
380 tftf_testcase_printf("Test not ported to AArch32\n");
381 return TEST_RESULT_SKIPPED;
382}
383
Manish Pandey5f513d62022-01-17 11:05:53 +0000384#endif /* __aarch64__ */