blob: 04fff01debbc1f785eeae5a41eab77078143a259 [file] [log] [blame]
Manish Pandey5f513d62022-01-17 11:05:53 +00001/*
Karl Meakin1331a8c2023-09-14 16:25:15 +01002 * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
Manish Pandey5f513d62022-01-17 11:05:53 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Karl Meakin1331a8c2023-09-14 16:25:15 +01007#include "ffa_helpers.h"
Olivier Deprez82bbc572022-01-11 11:50:36 +01008#include <plat/common/platform.h>
9
Manish Pandey5f513d62022-01-17 11:05:53 +000010#include <arch.h>
11#include <arch_helpers.h>
12#include <arch_features.h>
13#include <debug.h>
14#ifdef __aarch64__
Daniel Boulby82bf3392023-07-28 18:32:27 +010015#include <spm_test_helpers.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000016#include <sync.h>
17#endif
nabkah01002e5692022-10-10 12:36:46 +010018#include <host_realm_helper.h>
Olivier Deprez82bbc572022-01-11 11:50:36 +010019#include <lib/aarch64/arch_features.h>
nabkah01002e5692022-10-10 12:36:46 +010020#include <test_helpers.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000021#include <tftf_lib.h>
Manish Pandey368054b2022-03-15 13:24:59 +000022#include <xlat_tables_v2.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000023#include <platform_def.h>
nabkah0146b418d2022-02-16 17:01:54 +000024#include <cactus_test_cmds.h>
25#include <ffa_endpoints.h>
26
Manish Pandey5f513d62022-01-17 11:05:53 +000027/*
28 * Using "__aarch64__" here looks weird but its unavoidable because of following reason
29 * This test is part of standard test which runs on all platforms but pre-requisite
30 * to run this test (custom sync exception handler) is only implemented for aarch64.
31 * TODO: Write a framework so that tests kept in standard list can be selectively
32 * run on a given architecture
33 */
34#ifdef __aarch64__
35
nabkah0146b418d2022-02-16 17:01:54 +000036#define SENDER HYP_ID
37#define RECEIVER SP_ID(1)
38
Manish Pandey5f513d62022-01-17 11:05:53 +000039static volatile bool sync_exception_triggered;
40static volatile bool data_abort_triggered;
nabkah0146b418d2022-02-16 17:01:54 +000041static const struct ffa_uuid expected_sp_uuids[] = {
42 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
43};
Manish Pandey5f513d62022-01-17 11:05:53 +000044
Olivier Deprez82bbc572022-01-11 11:50:36 +010045static __aligned(PAGE_SIZE) uint64_t share_page[PAGE_SIZE / sizeof(uint64_t)];
46
Manish Pandey5f513d62022-01-17 11:05:53 +000047static bool data_abort_handler(void)
48{
49 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
50 unsigned int rme_supported = get_armv9_2_feat_rme_support();
51
52 sync_exception_triggered = true;
53
54 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
55
56 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
57 if (rme_supported == 0) {
58 /* Synchronous external data abort triggered by trustzone controller */
59 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
60 VERBOSE("%s TZC Data Abort caught\n", __func__);
61 data_abort_triggered = true;
62 return true;
63 }
64 } else {
65 /* Synchronous data abort triggered by Granule protection */
66 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
67 VERBOSE("%s GPF Data Abort caught\n", __func__);
68 data_abort_triggered = true;
69 return true;
70 }
71 }
72 }
73
74 return false;
75}
76
nabkah01bf00f8d2022-03-22 12:37:19 +000077test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +000078{
79 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
80
Manish Pandey5f513d62022-01-17 11:05:53 +000081 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
82
Manish Pandey368054b2022-03-15 13:24:59 +000083 sync_exception_triggered = false;
Manish Pandey5f513d62022-01-17 11:05:53 +000084 data_abort_triggered = false;
Manish Pandey368054b2022-03-15 13:24:59 +000085
86 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
87 MT_MEMORY | MT_RW | MT_NS);
88 if (rc != 0) {
89 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
90 return TEST_RESULT_FAIL;
91 }
92
Manish Pandey5f513d62022-01-17 11:05:53 +000093 register_custom_sync_exception_handler(data_abort_handler);
Manish Pandey5f513d62022-01-17 11:05:53 +000094 *((volatile uint64_t *)test_address);
Manish Pandey5f513d62022-01-17 11:05:53 +000095 unregister_custom_sync_exception_handler();
96
Manish Pandey368054b2022-03-15 13:24:59 +000097 rc = mmap_remove_dynamic_region(test_address, PAGE_SIZE);
98 if (rc != 0) {
99 tftf_testcase_printf("%d: mmap_remove_dynamic_region() = %d\n", __LINE__, rc);
100 return TEST_RESULT_FAIL;
101 }
102
Manish Pandey5f513d62022-01-17 11:05:53 +0000103 if (sync_exception_triggered == false) {
104 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
105 return TEST_RESULT_SKIPPED;
106 }
107
108 if (data_abort_triggered == false) {
109 tftf_testcase_printf("Sync exception is not data abort\n");
110 return TEST_RESULT_FAIL;
111 }
112
113 return TEST_RESULT_SUCCESS;
114}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100115
116/**
117 * @Test_Aim@ Check a realm region cannot be accessed from normal world.
118 *
119 * This test delegates a TFTF allocated buffer to Realm. It then attempts
120 * a read access to the region from normal world. This results in the PE
121 * triggering a GPF caught by a custom synchronous abort handler.
122 *
123 */
124test_result_t rl_memory_cannot_be_accessed_in_ns(void)
125{
126 test_result_t result = TEST_RESULT_FAIL;
127 u_register_t retmm;
128
129 if (get_armv9_2_feat_rme_support() == 0U) {
130 return TEST_RESULT_SKIPPED;
131 }
132
133 sync_exception_triggered = false;
134 data_abort_triggered = false;
135 register_custom_sync_exception_handler(data_abort_handler);
136
137 /* First read access to the test region must not fail. */
138 *((volatile uint64_t *)share_page);
139
140 if ((sync_exception_triggered != false) ||
141 (data_abort_triggered != false)) {
142 goto out_unregister;
143 }
144
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000145 host_rmi_init_cmp_result();
AlexeiFedorov380b2af2022-11-23 17:31:27 +0000146
Olivier Deprez82bbc572022-01-11 11:50:36 +0100147 /* Delegate the shared page to Realm. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000148 retmm = host_rmi_granule_delegate((u_register_t)&share_page);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100149 if (retmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000150 ERROR("%s() failed\n", "host_rmi_granule_delegate");
Olivier Deprez82bbc572022-01-11 11:50:36 +0100151 goto out_unregister;
152 }
153
154 /* This access shall trigger a GPF. */
155 *((volatile uint64_t *)share_page);
156
157 if ((sync_exception_triggered != true) ||
158 (data_abort_triggered != true)) {
159 goto out_undelegate;
160 }
161
AlexeiFedorov380b2af2022-11-23 17:31:27 +0000162 result = host_cmp_result();
Olivier Deprez82bbc572022-01-11 11:50:36 +0100163
164out_undelegate:
165 /* Undelegate the shared page. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000166 retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100167 if (retmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000168 ERROR("Granule undelegate failed, ret=0x%lx\n", retmm);
Olivier Deprez82bbc572022-01-11 11:50:36 +0100169 }
170
171out_unregister:
172 unregister_custom_sync_exception_handler();
173
174 return result;
175}
176
nabkah01bf00f8d2022-03-22 12:37:19 +0000177/**
178 * @Test_Aim@ Check a secure region cannot be accessed from normal world.
179 *
180 * Following test intends to run on RME enabled platforms when EL3
181 * is Root world. In a non RME platform, EL3 is secure.
182 * Access to secure memory from NS world is already covered
183 * by el3_memory_cannot_be_accessed_in_ns.
184 */
185test_result_t s_memory_cannot_be_accessed_in_ns(void)
186{
187 const uintptr_t test_address = SECURE_MEMORY_ACCESS_ADDR;
188
189 /* skipp non RME platforms */
190 if (get_armv9_2_feat_rme_support() == 0U) {
191 return TEST_RESULT_SKIPPED;
192 }
193
194 VERBOSE("Attempt to access secure memory (0x%lx)\n", test_address);
195
196 data_abort_triggered = false;
197 sync_exception_triggered = false;
198 register_custom_sync_exception_handler(data_abort_handler);
199 dsbsy();
200
201 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
202 MT_MEMORY | MT_RW | MT_NS);
203
204 if (rc != 0) {
205 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
206 return TEST_RESULT_FAIL;
207 }
208
209 *((volatile uint64_t *)test_address);
210
211 mmap_remove_dynamic_region(test_address, PAGE_SIZE);
212
213 dsbsy();
214 unregister_custom_sync_exception_handler();
215
216 if (sync_exception_triggered == false) {
217 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
218 return TEST_RESULT_SKIPPED;
219 }
220
221 if (data_abort_triggered == false) {
222 tftf_testcase_printf("Sync exception is not data abort\n");
223 return TEST_RESULT_FAIL;
224 }
225
226 return TEST_RESULT_SUCCESS;
227}
228
nabkah01905b2c72022-02-10 10:46:32 +0000229static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
230{
231 u_register_t retrmm;
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000232 test_result_t result = TEST_RESULT_FAIL;
nabkah01905b2c72022-02-10 10:46:32 +0000233 static char rd[GRANULE_SIZE] __aligned(GRANULE_SIZE);
234
Arunachalam Ganapathy4b221112023-04-05 14:19:03 +0100235 SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
nabkah01905b2c72022-02-10 10:46:32 +0000236
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000237 retrmm = host_rmi_granule_delegate((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000238 if (retrmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000239 ERROR("%s() failed, ret=0x%lx\n", "host_rmi_granule_delegate",
240 retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000241 return TEST_RESULT_FAIL;
242 }
243
244 /* Create a realm using a parameter in a secure physical address space should fail. */
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000245 retrmm = host_rmi_realm_create((u_register_t)&rd[0], params);
nabkah01905b2c72022-02-10 10:46:32 +0000246 if (retrmm == 0UL) {
247 ERROR("Realm create operation should fail, %lx\n", retrmm);
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000248 retrmm = host_rmi_realm_destroy((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000249 if (retrmm != 0UL) {
250 ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000251 }
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000252 } else if (retrmm != RMI_ERROR_INPUT) {
253 ERROR("Realm create operation should fail with code:%d retrmm:%ld\n",
254 RMI_ERROR_INPUT, retrmm);
255 } else {
256 result = TEST_RESULT_SUCCESS;
nabkah01905b2c72022-02-10 10:46:32 +0000257 }
258
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000259 retrmm = host_rmi_granule_undelegate((u_register_t)&rd[0]);
nabkah01905b2c72022-02-10 10:46:32 +0000260 if (retrmm != 0UL) {
AlexeiFedorov2f30f102023-03-13 19:37:46 +0000261 INFO("Undelegate operation returns 0x%lx\n", retrmm);
nabkah01905b2c72022-02-10 10:46:32 +0000262 return TEST_RESULT_FAIL;
263 }
264
AlexeiFedorovc21694d2022-12-16 12:19:52 +0000265 if (result == TEST_RESULT_SUCCESS) {
266 return host_cmp_result();
267 }
268
269 return TEST_RESULT_FAIL;
nabkah01905b2c72022-02-10 10:46:32 +0000270}
271
nabkah0146b418d2022-02-16 17:01:54 +0000272/**
273 * @Test_Aim@ Check a root region cannot be accessed from a secure partition.
274 *
nabkah0146b418d2022-02-16 17:01:54 +0000275 * A hardcoded address marked Root in the GPT is shared to a secure
J-Alves2e58e732023-05-05 11:57:48 +0100276 * partition. The operation fails given the memory shared needs to be
277 * preconfigured in the memory ranges described in the SPMC manifest. The ranges
278 * related with S/NS memory that the SP can access shall never contain
279 * realm/root memory as this incurs into a configuration error.
280 * This test validates the SP can't get access to root memory via FF-A memory
281 * sharing interfaces.
nabkah0146b418d2022-02-16 17:01:54 +0000282 */
283test_result_t rt_memory_cannot_be_accessed_in_s(void)
284{
285 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
286 struct ffa_memory_region_constituent constituents[] = {
287 {
288 (void *)test_address, 1, 0
289 }
290 };
291 const uint32_t constituents_count = sizeof(constituents) /
292 sizeof(struct ffa_memory_region_constituent);
293 ffa_memory_handle_t handle;
294 struct mailbox_buffers mb;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100295 struct ffa_value ret;
nabkah0146b418d2022-02-16 17:01:54 +0000296
Karl Meakin1331a8c2023-09-14 16:25:15 +0100297 struct ffa_memory_access receiver =
298 ffa_memory_access_init_permissions_from_mem_func(
J-Alves8984e722024-05-07 22:21:54 +0100299 RECEIVER, FFA_MEM_SHARE_SMC64);
Karl Meakin1331a8c2023-09-14 16:25:15 +0100300
nabkah0146b418d2022-02-16 17:01:54 +0000301 if (get_armv9_2_feat_rme_support() == 0U) {
302 return TEST_RESULT_SKIPPED;
303 }
304
Daniel Boulbyb34fe102024-01-17 15:10:52 +0000305 CHECK_SPMC_TESTING_SETUP(1, 2, expected_sp_uuids);
Olivier Deprezfac8ed72022-12-20 11:09:43 +0100306
nabkah0146b418d2022-02-16 17:01:54 +0000307 GET_TFTF_MAILBOX(mb);
308
Karl Meakin0d4f5ff2023-10-13 20:03:16 +0100309 handle = memory_init_and_send(mb.send, PAGE_SIZE, SENDER, &receiver, 1,
Karl Meakin1331a8c2023-09-14 16:25:15 +0100310 constituents, constituents_count,
J-Alves8984e722024-05-07 22:21:54 +0100311 FFA_MEM_SHARE_SMC64, &ret);
nabkah0146b418d2022-02-16 17:01:54 +0000312
313 if (handle == FFA_MEMORY_HANDLE_INVALID) {
J-Alves2e58e732023-05-05 11:57:48 +0100314 return TEST_RESULT_SUCCESS;
nabkah0146b418d2022-02-16 17:01:54 +0000315 }
316
J-Alves2e58e732023-05-05 11:57:48 +0100317 return TEST_RESULT_FAIL;
nabkah0146b418d2022-02-16 17:01:54 +0000318}
319
nabkah01905b2c72022-02-10 10:46:32 +0000320test_result_t s_memory_cannot_be_accessed_in_rl(void)
321{
322 u_register_t params = (u_register_t)SECURE_MEMORY_ACCESS_ADDR;
323 return memory_cannot_be_accessed_in_rl(params);
324}
325
nabkah01e7147862022-02-11 19:08:00 +0000326test_result_t rt_memory_cannot_be_accessed_in_rl(void)
327{
328 u_register_t params = (u_register_t)EL3_MEMORY_ACCESS_ADDR;
329 return memory_cannot_be_accessed_in_rl(params);
330}
331
Manish Pandey5f513d62022-01-17 11:05:53 +0000332#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100333
nabkah01bf00f8d2022-03-22 12:37:19 +0000334test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +0000335{
336 tftf_testcase_printf("Test not ported to AArch32\n");
337 return TEST_RESULT_SKIPPED;
338}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100339
340test_result_t rl_memory_cannot_be_accessed_in_ns(void)
341{
342 tftf_testcase_printf("Test not ported to AArch32\n");
343 return TEST_RESULT_SKIPPED;
344}
345
nabkah01bf00f8d2022-03-22 12:37:19 +0000346test_result_t s_memory_cannot_be_accessed_in_ns(void)
347{
348 tftf_testcase_printf("Test not ported to AArch32\n");
349 return TEST_RESULT_SKIPPED;
350}
nabkah01905b2c72022-02-10 10:46:32 +0000351
352test_result_t s_memory_cannot_be_accessed_in_rl(void)
353{
354 tftf_testcase_printf("Test not ported to AArch32\n");
355 return TEST_RESULT_SKIPPED;
356}
357
nabkah01e7147862022-02-11 19:08:00 +0000358test_result_t rt_memory_cannot_be_accessed_in_rl(void)
359{
360 tftf_testcase_printf("Test not ported to AArch32\n");
361 return TEST_RESULT_SKIPPED;
362}
363
Manish Pandey5f513d62022-01-17 11:05:53 +0000364#endif /* __aarch64__ */