1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define TLOG_TAG "smc-test"
18 
19 #include <lib/smc/smc_ipc.h>
20 #include <lib/smc/smc_test.h>
21 #include <sys/mman.h>
22 #include <trusty/sys/mman.h>
23 #include <trusty_ipc.h>
24 #include <trusty_unittest.h>
25 #include <uapi/err.h>
26 
27 typedef struct smc {
28     handle_t channel;
29 } smc_t;
30 
31 static const int msg_len = sizeof(struct smc_msg);
32 
TEST_F_SETUP(smc)33 TEST_F_SETUP(smc) {
34     int rc;
35 
36     rc = connect(SMC_SERVICE_PORT, IPC_CONNECT_WAIT_FOR_PORT);
37     _state->channel = (handle_t)rc;
38     ASSERT_GT(_state->channel, 0);
39 
40 test_abort:;
41 }
42 
TEST_F_TEARDOWN(smc)43 TEST_F_TEARDOWN(smc) {
44     close(_state->channel);
45 }
46 
47 /* Macro to enable test cases for platform(s) on ARM and ARM64 architectures */
48 #if defined(ARCH_ARM) || defined(ARCH_ARM64)
49 #define ARM_ONLY_TEST(name) name
50 #else
51 #define ARM_ONLY_TEST(name) DISABLED_##name
52 #endif
53 
54 /* Macro to enable test cases for generic ARM64 platform only */
55 #if defined(PLATFORM_GENERIC_ARM64)
56 #define GENERIC_ARM64_PLATFORM_ONLY_TEST(name) name
57 #else
58 #define GENERIC_ARM64_PLATFORM_ONLY_TEST(name) DISABLED_##name
59 #endif
60 
61 /* Check that SM_ERR_UNDEFINED_SMC is returned for an unknown SMC number */
TEST_F(smc,ARM_ONLY_TEST (unknown_smc))62 TEST_F(smc, ARM_ONLY_TEST(unknown_smc)) {
63     int rc;
64     struct smc_msg request = {
65             .params[0] = ILLEGAL_SMC,
66     };
67     struct smc_msg response;
68 
69     rc = smc_send_request(_state->channel, &request);
70     ASSERT_EQ(rc, msg_len);
71 
72     rc = smc_read_response(_state->channel, &response);
73     ASSERT_EQ(rc, ERR_GENERIC);
74     ASSERT_EQ((int32_t)response.params[0], SM_ERR_UNDEFINED_SMC);
75 
76 test_abort:;
77 }
78 
79 /* Check that SMC service supports clients on multiple channels */
TEST_F(smc,ARM_ONLY_TEST (multiple_channels))80 TEST_F(smc, ARM_ONLY_TEST(multiple_channels)) {
81     int rc;
82     handle_t channel1;
83     handle_t channel2;
84     struct smc_msg request = {
85             .params[0] = ILLEGAL_SMC,
86     };
87     struct smc_msg response;
88 
89     channel1 = _state->channel;
90 
91     rc = connect(SMC_SERVICE_PORT, IPC_CONNECT_WAIT_FOR_PORT);
92     channel2 = (handle_t)rc;
93     ASSERT_GT(channel2, 0);
94 
95     rc = smc_send_request(channel1, &request);
96     ASSERT_EQ(rc, msg_len);
97 
98     rc = smc_send_request(channel2, &request);
99     ASSERT_EQ(rc, msg_len);
100 
101     rc = smc_read_response(channel1, &response);
102     ASSERT_EQ(rc, ERR_GENERIC);
103     ASSERT_EQ((int32_t)response.params[0], SM_ERR_UNDEFINED_SMC);
104 
105     rc = smc_read_response(channel2, &response);
106     ASSERT_EQ(rc, ERR_GENERIC);
107     ASSERT_EQ((int32_t)response.params[0], SM_ERR_UNDEFINED_SMC);
108 
109 test_abort:
110     close(channel2);
111 }
112 
113 /* Following test cases rely on Trusty SPD to be enabled in EL3, and are thus
114  * platform-specific. */
115 
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (putc))116 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(putc)) {
117     int rc;
118     struct smc_msg request = {
119             .params[0] = SMC_FC_DEBUG_PUTC,
120             .params[1] = 'd', /* prints 'd' to serial */
121     };
122     struct smc_msg response;
123 
124     rc = smc_send_request(_state->channel, &request);
125     ASSERT_EQ(rc, msg_len);
126 
127     rc = smc_read_response(_state->channel, &response);
128     ASSERT_EQ(rc, msg_len);
129     ASSERT_EQ(response.params[0], 0);
130 
131 test_abort:;
132 }
133 
134 /* Check that we can query GICD base value from ATF */
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (get_gicd_base))135 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(get_gicd_base)) {
136     int rc;
137     struct smc_msg request = {
138             .params[0] = SMC_FC_GET_REG_BASE,
139             .params[1] = SMC_GET_GIC_BASE_GICD,
140     };
141     struct smc_msg response;
142 
143     rc = smc_send_request(_state->channel, &request);
144     ASSERT_EQ(rc, msg_len);
145 
146     rc = smc_read_response(_state->channel, &response);
147     ASSERT_EQ(rc, msg_len);
148     ASSERT_EQ(response.params[0], GICD_BASE);
149 
150 test_abort:;
151 }
152 
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (get_gicc_base))153 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(get_gicc_base)) {
154     int rc;
155     struct smc_msg request = {
156             .params[0] = SMC_FC_GET_REG_BASE,
157             .params[1] = SMC_GET_GIC_BASE_GICC,
158     };
159     struct smc_msg response;
160 
161     rc = smc_send_request(_state->channel, &request);
162     ASSERT_EQ(rc, msg_len);
163 
164     rc = smc_read_response(_state->channel, &response);
165     ASSERT_EQ(rc, msg_len);
166     ASSERT_EQ(response.params[0], GICC_BASE);
167 
168 test_abort:;
169 }
170 
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (access_denied))171 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(access_denied)) {
172     int rc;
173     struct smc_msg request = {
174             .params[0] = SMC_FC_ECHO_ONE_ARG,
175     };
176     struct smc_msg response;
177 
178     rc = smc_send_request(_state->channel, &request);
179     ASSERT_EQ(rc, msg_len);
180 
181     rc = smc_read_response(_state->channel, &response);
182     ASSERT_EQ(rc, ERR_ACCESS_DENIED);
183     ASSERT_EQ((int32_t)response.params[0], ERR_ACCESS_DENIED);
184 
185 test_abort:;
186 }
187 
188 #if defined(ARCH_ARM)
189 #define ARCH_SMC_FC_ECHO_THREE_ARGS SMC_FC_ECHO_THREE_ARGS
190 #else
191 #define ARCH_SMC_FC_ECHO_THREE_ARGS SMC_FC64_ECHO_THREE_ARGS
192 #endif
193 
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (invalid_arguments))194 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(invalid_arguments)) {
195     int rc;
196     struct smc_msg request = {
197             .params[0] = ARCH_SMC_FC_ECHO_THREE_ARGS,
198             .params[1] = SMC_ACCESS_CONTROL_ALLOW_ARGS,
199             .params[2] = 0,
200     };
201     struct smc_msg response;
202 
203     rc = smc_send_request(_state->channel, &request);
204     ASSERT_EQ(rc, msg_len);
205 
206     rc = smc_read_response(_state->channel, &response);
207     ASSERT_EQ(rc, msg_len);
208     ASSERT_EQ(response.params[0], ARCH_SMC_FC_ECHO_THREE_ARGS);
209     ASSERT_EQ(response.params[1], SMC_ACCESS_CONTROL_ALLOW_ARGS);
210 
211     /* should fail validation per service access policy */
212     request.params[1] = SMC_ACCESS_CONTROL_VALIDATE_ARGS;
213 
214     rc = smc_send_request(_state->channel, &request);
215     ASSERT_EQ(rc, msg_len);
216 
217     rc = smc_read_response(_state->channel, &response);
218     ASSERT_EQ(rc, ERR_INVALID_ARGS);
219     ASSERT_EQ((int32_t)response.params[0], ERR_INVALID_ARGS);
220 
221 test_abort:;
222 }
223 
TEST_F(smc,GENERIC_ARM64_PLATFORM_ONLY_TEST (validate_dma_arguments))224 TEST_F(smc, GENERIC_ARM64_PLATFORM_ONLY_TEST(validate_dma_arguments)) {
225     const uint32_t dma_flags = DMA_FLAG_FROM_DEVICE | DMA_FLAG_ALLOW_PARTIAL;
226     const uint32_t len = 0x1000U;
227     uint8_t* va_base = MAP_FAILED;
228     int rc;
229     struct smc_msg request = {
230             .params[0] = ARCH_SMC_FC_ECHO_THREE_ARGS,
231             .params[1] = SMC_ACCESS_CONTROL_VALIDATE_ARGS,
232             .params[2] = 0, /* invalid per test policy */
233     };
234     struct smc_msg response;
235     struct dma_pmem pmem;
236 
237     rc = smc_send_request(_state->channel, &request);
238     ASSERT_EQ(rc, msg_len);
239 
240     rc = smc_read_response(_state->channel, &response);
241     ASSERT_EQ(rc, ERR_INVALID_ARGS);
242     ASSERT_EQ((int32_t)response.params[0], ERR_INVALID_ARGS);
243 
244     va_base = mmap(NULL, len, PROT_READ | PROT_WRITE, MMAP_FLAG_IO_HANDLE,
245                    /* MMAP_ID=*/1, 0);
246     ASSERT_NE(va_base, MAP_FAILED);
247 
248     rc = prepare_dma((void*)va_base, len, dma_flags, &pmem);
249     ASSERT_EQ(rc, 1);
250     ASSERT_NE(pmem.paddr, 0);
251     ASSERT_EQ(pmem.size, len);
252 
253     request.params[2] = pmem.paddr;
254 
255     rc = smc_send_request(_state->channel, &request);
256     ASSERT_EQ(rc, msg_len);
257 
258     rc = smc_read_response(_state->channel, &response);
259     ASSERT_EQ(rc, msg_len);
260     ASSERT_EQ(response.params[0], (uint64_t)ARCH_SMC_FC_ECHO_THREE_ARGS);
261     ASSERT_EQ(response.params[1], SMC_ACCESS_CONTROL_VALIDATE_ARGS);
262     ASSERT_EQ(response.params[2], pmem.paddr);
263 
264     /* fallthrough */
265 test_abort:
266     finish_dma(va_base, len, dma_flags);
267     munmap(va_base, len);
268 }
269 
270 PORT_TEST(smc, "com.android.trusty.smc.test");
271