blob: 1e584afdae8d7a0a90fb1efd5e89b09b9d7ac9d6 [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
68test_result_t access_el3_memory_from_ns(void)
69{
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
Manish Pandey5f513d62022-01-17 11:05:53 +0000166#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100167
Manish Pandey5f513d62022-01-17 11:05:53 +0000168test_result_t access_el3_memory_from_ns(void)
169{
170 tftf_testcase_printf("Test not ported to AArch32\n");
171 return TEST_RESULT_SKIPPED;
172}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100173
174test_result_t rl_memory_cannot_be_accessed_in_ns(void)
175{
176 tftf_testcase_printf("Test not ported to AArch32\n");
177 return TEST_RESULT_SKIPPED;
178}
179
Manish Pandey5f513d62022-01-17 11:05:53 +0000180#endif /* __aarch64__ */