blob: 12cd4b5160e7022f68f62880ed054d692fd357ca [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__
14#include <sync.h>
15#endif
16#include <test_helpers.h>
Olivier Deprez82bbc572022-01-11 11:50:36 +010017#include <lib/aarch64/arch_features.h>
18#include <runtime_services/realm_payload/realm_payload_test.h>
Manish Pandey5f513d62022-01-17 11:05:53 +000019#include <tftf_lib.h>
Manish Pandey368054b2022-03-15 13:24:59 +000020#include <xlat_tables_v2.h>
21
Manish Pandey5f513d62022-01-17 11:05:53 +000022#include <platform_def.h>
23
24/*
25 * Using "__aarch64__" here looks weird but its unavoidable because of following reason
26 * This test is part of standard test which runs on all platforms but pre-requisite
27 * to run this test (custom sync exception handler) is only implemented for aarch64.
28 * TODO: Write a framework so that tests kept in standard list can be selectively
29 * run on a given architecture
30 */
31#ifdef __aarch64__
32
Manish Pandey5f513d62022-01-17 11:05:53 +000033static volatile bool sync_exception_triggered;
34static volatile bool data_abort_triggered;
35
Olivier Deprez82bbc572022-01-11 11:50:36 +010036static __aligned(PAGE_SIZE) uint64_t share_page[PAGE_SIZE / sizeof(uint64_t)];
37
Manish Pandey5f513d62022-01-17 11:05:53 +000038static bool data_abort_handler(void)
39{
40 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
41 unsigned int rme_supported = get_armv9_2_feat_rme_support();
42
43 sync_exception_triggered = true;
44
45 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
46
47 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
48 if (rme_supported == 0) {
49 /* Synchronous external data abort triggered by trustzone controller */
50 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
51 VERBOSE("%s TZC Data Abort caught\n", __func__);
52 data_abort_triggered = true;
53 return true;
54 }
55 } else {
56 /* Synchronous data abort triggered by Granule protection */
57 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
58 VERBOSE("%s GPF Data Abort caught\n", __func__);
59 data_abort_triggered = true;
60 return true;
61 }
62 }
63 }
64
65 return false;
66}
67
nabkah01bf00f8d2022-03-22 12:37:19 +000068test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +000069{
70 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
71
Manish Pandey5f513d62022-01-17 11:05:53 +000072 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
73
Manish Pandey368054b2022-03-15 13:24:59 +000074 sync_exception_triggered = false;
Manish Pandey5f513d62022-01-17 11:05:53 +000075 data_abort_triggered = false;
Manish Pandey368054b2022-03-15 13:24:59 +000076
77 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
78 MT_MEMORY | MT_RW | MT_NS);
79 if (rc != 0) {
80 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
81 return TEST_RESULT_FAIL;
82 }
83
Manish Pandey5f513d62022-01-17 11:05:53 +000084 register_custom_sync_exception_handler(data_abort_handler);
Manish Pandey5f513d62022-01-17 11:05:53 +000085 *((volatile uint64_t *)test_address);
Manish Pandey5f513d62022-01-17 11:05:53 +000086 unregister_custom_sync_exception_handler();
87
Manish Pandey368054b2022-03-15 13:24:59 +000088 rc = mmap_remove_dynamic_region(test_address, PAGE_SIZE);
89 if (rc != 0) {
90 tftf_testcase_printf("%d: mmap_remove_dynamic_region() = %d\n", __LINE__, rc);
91 return TEST_RESULT_FAIL;
92 }
93
Manish Pandey5f513d62022-01-17 11:05:53 +000094 if (sync_exception_triggered == false) {
95 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
96 return TEST_RESULT_SKIPPED;
97 }
98
99 if (data_abort_triggered == false) {
100 tftf_testcase_printf("Sync exception is not data abort\n");
101 return TEST_RESULT_FAIL;
102 }
103
104 return TEST_RESULT_SUCCESS;
105}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100106
107/**
108 * @Test_Aim@ Check a realm region cannot be accessed from normal world.
109 *
110 * This test delegates a TFTF allocated buffer to Realm. It then attempts
111 * a read access to the region from normal world. This results in the PE
112 * triggering a GPF caught by a custom synchronous abort handler.
113 *
114 */
115test_result_t rl_memory_cannot_be_accessed_in_ns(void)
116{
117 test_result_t result = TEST_RESULT_FAIL;
118 u_register_t retmm;
119
120 if (get_armv9_2_feat_rme_support() == 0U) {
121 return TEST_RESULT_SKIPPED;
122 }
123
124 sync_exception_triggered = false;
125 data_abort_triggered = false;
126 register_custom_sync_exception_handler(data_abort_handler);
127
128 /* First read access to the test region must not fail. */
129 *((volatile uint64_t *)share_page);
130
131 if ((sync_exception_triggered != false) ||
132 (data_abort_triggered != false)) {
133 goto out_unregister;
134 }
135
136 /* Delegate the shared page to Realm. */
137 retmm = realm_granule_delegate((u_register_t)&share_page);
138 if (retmm != 0UL) {
139 ERROR("Granule delegate failed!\n");
140 goto out_unregister;
141 }
142
143 /* This access shall trigger a GPF. */
144 *((volatile uint64_t *)share_page);
145
146 if ((sync_exception_triggered != true) ||
147 (data_abort_triggered != true)) {
148 goto out_undelegate;
149 }
150
151 result = TEST_RESULT_SUCCESS;
152
153out_undelegate:
154 /* Undelegate the shared page. */
155 retmm = realm_granule_undelegate((u_register_t)&share_page);
156 if (retmm != 0UL) {
157 ERROR("Granule undelegate failed!\n");
158 }
159
160out_unregister:
161 unregister_custom_sync_exception_handler();
162
163 return result;
164}
165
nabkah01bf00f8d2022-03-22 12:37:19 +0000166/**
167 * @Test_Aim@ Check a secure region cannot be accessed from normal world.
168 *
169 * Following test intends to run on RME enabled platforms when EL3
170 * is Root world. In a non RME platform, EL3 is secure.
171 * Access to secure memory from NS world is already covered
172 * by el3_memory_cannot_be_accessed_in_ns.
173 */
174test_result_t s_memory_cannot_be_accessed_in_ns(void)
175{
176 const uintptr_t test_address = SECURE_MEMORY_ACCESS_ADDR;
177
178 /* skipp non RME platforms */
179 if (get_armv9_2_feat_rme_support() == 0U) {
180 return TEST_RESULT_SKIPPED;
181 }
182
183 VERBOSE("Attempt to access secure memory (0x%lx)\n", test_address);
184
185 data_abort_triggered = false;
186 sync_exception_triggered = false;
187 register_custom_sync_exception_handler(data_abort_handler);
188 dsbsy();
189
190 int rc = mmap_add_dynamic_region(test_address, test_address, PAGE_SIZE,
191 MT_MEMORY | MT_RW | MT_NS);
192
193 if (rc != 0) {
194 tftf_testcase_printf("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
195 return TEST_RESULT_FAIL;
196 }
197
198 *((volatile uint64_t *)test_address);
199
200 mmap_remove_dynamic_region(test_address, PAGE_SIZE);
201
202 dsbsy();
203 unregister_custom_sync_exception_handler();
204
205 if (sync_exception_triggered == false) {
206 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
207 return TEST_RESULT_SKIPPED;
208 }
209
210 if (data_abort_triggered == false) {
211 tftf_testcase_printf("Sync exception is not data abort\n");
212 return TEST_RESULT_FAIL;
213 }
214
215 return TEST_RESULT_SUCCESS;
216}
217
nabkah01905b2c72022-02-10 10:46:32 +0000218static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
219{
220 u_register_t retrmm;
221 static char rd[GRANULE_SIZE] __aligned(GRANULE_SIZE);
222
223 if (get_armv9_2_feat_rme_support() == 0U) {
224 return TEST_RESULT_SKIPPED;
225 }
226
227 retrmm = realm_version();
228
229 VERBOSE("RMM version is: %lu.%lu\n",
230 RMI_ABI_VERSION_GET_MAJOR(retrmm),
231 RMI_ABI_VERSION_GET_MINOR(retrmm));
232
233 /*
234 * TODO: Remove this once SMC_RMM_REALM_CREATE is implemented in TRP
235 * For the moment skip the test if RMM is TRP, TRP version is always null.
236 */
237 if (retrmm == 0U) {
238 return TEST_RESULT_SKIPPED;
239 }
240
241 retrmm = realm_granule_delegate((u_register_t)&rd[0]);
242 if (retrmm != 0UL) {
243 ERROR("Delegate operation returns fail, %lx\n", retrmm);
244 return TEST_RESULT_FAIL;
245 }
246
247 /* Create a realm using a parameter in a secure physical address space should fail. */
248 retrmm = realm_create((u_register_t)&rd[0], params);
249 if (retrmm == 0UL) {
250 ERROR("Realm create operation should fail, %lx\n", retrmm);
251 retrmm = realm_destroy((u_register_t)&rd[0]);
252 if (retrmm != 0UL) {
253 ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
254 return TEST_RESULT_FAIL;
255 }
256 return TEST_RESULT_FAIL;
257 } else if (retrmm != RMM_STATUS_ERROR_INPUT) {
258 ERROR("Realm create operation should fail with code:%ld retrmm:%ld\n",
259 RMM_STATUS_ERROR_INPUT, retrmm);
260 return TEST_RESULT_FAIL;
261 }
262
263 retrmm = realm_granule_undelegate((u_register_t)&rd[0]);
264 if (retrmm != 0UL) {
265 INFO("Undelegate operation returns fail, %lx\n", retrmm);
266 return TEST_RESULT_FAIL;
267 }
268
269 return TEST_RESULT_SUCCESS;
270}
271
272test_result_t s_memory_cannot_be_accessed_in_rl(void)
273{
274 u_register_t params = (u_register_t)SECURE_MEMORY_ACCESS_ADDR;
275 return memory_cannot_be_accessed_in_rl(params);
276}
277
Manish Pandey5f513d62022-01-17 11:05:53 +0000278#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100279
nabkah01bf00f8d2022-03-22 12:37:19 +0000280test_result_t el3_memory_cannot_be_accessed_in_ns(void)
Manish Pandey5f513d62022-01-17 11:05:53 +0000281{
282 tftf_testcase_printf("Test not ported to AArch32\n");
283 return TEST_RESULT_SKIPPED;
284}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100285
286test_result_t rl_memory_cannot_be_accessed_in_ns(void)
287{
288 tftf_testcase_printf("Test not ported to AArch32\n");
289 return TEST_RESULT_SKIPPED;
290}
291
nabkah01bf00f8d2022-03-22 12:37:19 +0000292test_result_t s_memory_cannot_be_accessed_in_ns(void)
293{
294 tftf_testcase_printf("Test not ported to AArch32\n");
295 return TEST_RESULT_SKIPPED;
296}
nabkah01905b2c72022-02-10 10:46:32 +0000297
298test_result_t s_memory_cannot_be_accessed_in_rl(void)
299{
300 tftf_testcase_printf("Test not ported to AArch32\n");
301 return TEST_RESULT_SKIPPED;
302}
303
Manish Pandey5f513d62022-01-17 11:05:53 +0000304#endif /* __aarch64__ */