blob: 18b68fb2cfd04c0e0bd3290154c194a691912783 [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 Pandey5f513d62022-01-17 11:05:53 +000020#include <platform_def.h>
21
22/*
23 * Using "__aarch64__" here looks weird but its unavoidable because of following reason
24 * This test is part of standard test which runs on all platforms but pre-requisite
25 * to run this test (custom sync exception handler) is only implemented for aarch64.
26 * TODO: Write a framework so that tests kept in standard list can be selectively
27 * run on a given architecture
28 */
29#ifdef __aarch64__
30
Manish Pandey5f513d62022-01-17 11:05:53 +000031static volatile bool sync_exception_triggered;
32static volatile bool data_abort_triggered;
33
Olivier Deprez82bbc572022-01-11 11:50:36 +010034static __aligned(PAGE_SIZE) uint64_t share_page[PAGE_SIZE / sizeof(uint64_t)];
35
Manish Pandey5f513d62022-01-17 11:05:53 +000036static bool data_abort_handler(void)
37{
38 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
39 unsigned int rme_supported = get_armv9_2_feat_rme_support();
40
41 sync_exception_triggered = true;
42
43 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
44
45 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
46 if (rme_supported == 0) {
47 /* Synchronous external data abort triggered by trustzone controller */
48 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
49 VERBOSE("%s TZC Data Abort caught\n", __func__);
50 data_abort_triggered = true;
51 return true;
52 }
53 } else {
54 /* Synchronous data abort triggered by Granule protection */
55 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
56 VERBOSE("%s GPF Data Abort caught\n", __func__);
57 data_abort_triggered = true;
58 return true;
59 }
60 }
61 }
62
63 return false;
64}
65
66test_result_t access_el3_memory_from_ns(void)
67{
68 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
69
Manish Pandey5f513d62022-01-17 11:05:53 +000070 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
71
72 data_abort_triggered = false;
73 register_custom_sync_exception_handler(data_abort_handler);
74 dsbsy();
75
76 *((volatile uint64_t *)test_address);
77
78 dsbsy();
79 unregister_custom_sync_exception_handler();
80
81 if (sync_exception_triggered == false) {
82 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
83 return TEST_RESULT_SKIPPED;
84 }
85
86 if (data_abort_triggered == false) {
87 tftf_testcase_printf("Sync exception is not data abort\n");
88 return TEST_RESULT_FAIL;
89 }
90
91 return TEST_RESULT_SUCCESS;
92}
Olivier Deprez82bbc572022-01-11 11:50:36 +010093
94/**
95 * @Test_Aim@ Check a realm region cannot be accessed from normal world.
96 *
97 * This test delegates a TFTF allocated buffer to Realm. It then attempts
98 * a read access to the region from normal world. This results in the PE
99 * triggering a GPF caught by a custom synchronous abort handler.
100 *
101 */
102test_result_t rl_memory_cannot_be_accessed_in_ns(void)
103{
104 test_result_t result = TEST_RESULT_FAIL;
105 u_register_t retmm;
106
107 if (get_armv9_2_feat_rme_support() == 0U) {
108 return TEST_RESULT_SKIPPED;
109 }
110
111 sync_exception_triggered = false;
112 data_abort_triggered = false;
113 register_custom_sync_exception_handler(data_abort_handler);
114
115 /* First read access to the test region must not fail. */
116 *((volatile uint64_t *)share_page);
117
118 if ((sync_exception_triggered != false) ||
119 (data_abort_triggered != false)) {
120 goto out_unregister;
121 }
122
123 /* Delegate the shared page to Realm. */
124 retmm = realm_granule_delegate((u_register_t)&share_page);
125 if (retmm != 0UL) {
126 ERROR("Granule delegate failed!\n");
127 goto out_unregister;
128 }
129
130 /* This access shall trigger a GPF. */
131 *((volatile uint64_t *)share_page);
132
133 if ((sync_exception_triggered != true) ||
134 (data_abort_triggered != true)) {
135 goto out_undelegate;
136 }
137
138 result = TEST_RESULT_SUCCESS;
139
140out_undelegate:
141 /* Undelegate the shared page. */
142 retmm = realm_granule_undelegate((u_register_t)&share_page);
143 if (retmm != 0UL) {
144 ERROR("Granule undelegate failed!\n");
145 }
146
147out_unregister:
148 unregister_custom_sync_exception_handler();
149
150 return result;
151}
152
Manish Pandey5f513d62022-01-17 11:05:53 +0000153#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100154
Manish Pandey5f513d62022-01-17 11:05:53 +0000155test_result_t access_el3_memory_from_ns(void)
156{
157 tftf_testcase_printf("Test not ported to AArch32\n");
158 return TEST_RESULT_SKIPPED;
159}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100160
161test_result_t rl_memory_cannot_be_accessed_in_ns(void)
162{
163 tftf_testcase_printf("Test not ported to AArch32\n");
164 return TEST_RESULT_SKIPPED;
165}
166
Manish Pandey5f513d62022-01-17 11:05:53 +0000167#endif /* __aarch64__ */