blob: 2fb65421f462005d37560092ca113ad577174e15 [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
31#ifndef EL3_MEMORY_ACCESS_ADDR
32#define EL3_MEMORY_ACCESS_ADDR U(0xFFFFFFFF)
33#endif
34
35static volatile bool sync_exception_triggered;
36static volatile bool data_abort_triggered;
37
Olivier Deprez82bbc572022-01-11 11:50:36 +010038static __aligned(PAGE_SIZE) uint64_t share_page[PAGE_SIZE / sizeof(uint64_t)];
39
Manish Pandey5f513d62022-01-17 11:05:53 +000040static bool data_abort_handler(void)
41{
42 uint64_t esr_elx = IS_IN_EL2() ? read_esr_el2() : read_esr_el1();
43 unsigned int rme_supported = get_armv9_2_feat_rme_support();
44
45 sync_exception_triggered = true;
46
47 VERBOSE("%s esr_elx %llx\n", __func__, esr_elx);
48
49 if (EC_BITS(esr_elx) == EC_DABORT_CUR_EL) {
50 if (rme_supported == 0) {
51 /* Synchronous external data abort triggered by trustzone controller */
52 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_EXT_DABORT) {
53 VERBOSE("%s TZC Data Abort caught\n", __func__);
54 data_abort_triggered = true;
55 return true;
56 }
57 } else {
58 /* Synchronous data abort triggered by Granule protection */
59 if ((ISS_BITS(esr_elx) & ISS_DFSC_MASK) == DFSC_GPF_DABORT) {
60 VERBOSE("%s GPF Data Abort caught\n", __func__);
61 data_abort_triggered = true;
62 return true;
63 }
64 }
65 }
66
67 return false;
68}
69
70test_result_t access_el3_memory_from_ns(void)
71{
72 const uintptr_t test_address = EL3_MEMORY_ACCESS_ADDR;
73
74 SKIP_TEST_IF_INVALID_ADDRESS(test_address);
75
76 VERBOSE("Attempt to access el3 memory (0x%lx)\n", test_address);
77
78 data_abort_triggered = false;
79 register_custom_sync_exception_handler(data_abort_handler);
80 dsbsy();
81
82 *((volatile uint64_t *)test_address);
83
84 dsbsy();
85 unregister_custom_sync_exception_handler();
86
87 if (sync_exception_triggered == false) {
88 tftf_testcase_printf("No sync exception while accessing (0x%lx)\n", test_address);
89 return TEST_RESULT_SKIPPED;
90 }
91
92 if (data_abort_triggered == false) {
93 tftf_testcase_printf("Sync exception is not data abort\n");
94 return TEST_RESULT_FAIL;
95 }
96
97 return TEST_RESULT_SUCCESS;
98}
Olivier Deprez82bbc572022-01-11 11:50:36 +010099
100/**
101 * @Test_Aim@ Check a realm region cannot be accessed from normal world.
102 *
103 * This test delegates a TFTF allocated buffer to Realm. It then attempts
104 * a read access to the region from normal world. This results in the PE
105 * triggering a GPF caught by a custom synchronous abort handler.
106 *
107 */
108test_result_t rl_memory_cannot_be_accessed_in_ns(void)
109{
110 test_result_t result = TEST_RESULT_FAIL;
111 u_register_t retmm;
112
113 if (get_armv9_2_feat_rme_support() == 0U) {
114 return TEST_RESULT_SKIPPED;
115 }
116
117 sync_exception_triggered = false;
118 data_abort_triggered = false;
119 register_custom_sync_exception_handler(data_abort_handler);
120
121 /* First read access to the test region must not fail. */
122 *((volatile uint64_t *)share_page);
123
124 if ((sync_exception_triggered != false) ||
125 (data_abort_triggered != false)) {
126 goto out_unregister;
127 }
128
129 /* Delegate the shared page to Realm. */
130 retmm = realm_granule_delegate((u_register_t)&share_page);
131 if (retmm != 0UL) {
132 ERROR("Granule delegate failed!\n");
133 goto out_unregister;
134 }
135
136 /* This access shall trigger a GPF. */
137 *((volatile uint64_t *)share_page);
138
139 if ((sync_exception_triggered != true) ||
140 (data_abort_triggered != true)) {
141 goto out_undelegate;
142 }
143
144 result = TEST_RESULT_SUCCESS;
145
146out_undelegate:
147 /* Undelegate the shared page. */
148 retmm = realm_granule_undelegate((u_register_t)&share_page);
149 if (retmm != 0UL) {
150 ERROR("Granule undelegate failed!\n");
151 }
152
153out_unregister:
154 unregister_custom_sync_exception_handler();
155
156 return result;
157}
158
Manish Pandey5f513d62022-01-17 11:05:53 +0000159#else
Olivier Deprez82bbc572022-01-11 11:50:36 +0100160
Manish Pandey5f513d62022-01-17 11:05:53 +0000161test_result_t access_el3_memory_from_ns(void)
162{
163 tftf_testcase_printf("Test not ported to AArch32\n");
164 return TEST_RESULT_SKIPPED;
165}
Olivier Deprez82bbc572022-01-11 11:50:36 +0100166
167test_result_t rl_memory_cannot_be_accessed_in_ns(void)
168{
169 tftf_testcase_printf("Test not ported to AArch32\n");
170 return TEST_RESULT_SKIPPED;
171}
172
Manish Pandey5f513d62022-01-17 11:05:53 +0000173#endif /* __aarch64__ */