1 /*
2  * Copyright 2021 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #include "hf/dlog.h"
10 
11 #include "vmapi/hf/call.h"
12 
13 #include "primary_with_secondary.h"
14 #include "test/hftest.h"
15 #include "test/vmapi/exception_handler.h"
16 #include "test/vmapi/ffa.h"
17 
TEAR_DOWN(boot)18 TEAR_DOWN(boot)
19 {
20 	EXPECT_FFA_ERROR(ffa_rx_release(), FFA_DENIED);
21 }
22 
23 /**
24  * The VM gets its memory size on boot, and can access it all.
25  */
TEST(boot,memory_size)26 TEST(boot, memory_size)
27 {
28 	struct ffa_value run_res;
29 	struct mailbox_buffers mb = set_up_mailbox();
30 
31 	SERVICE_SELECT(SERVICE_VM1, "boot_memory", mb.send);
32 
33 	run_res = ffa_run(SERVICE_VM1, 0);
34 	EXPECT_EQ(run_res.func, FFA_YIELD_32);
35 }
36 
37 /**
38  * Accessing memory outside the given range traps the VM and yields.
39  */
TEST(boot,beyond_memory_size)40 TEST(boot, beyond_memory_size)
41 {
42 	struct ffa_value run_res;
43 	struct mailbox_buffers mb = set_up_mailbox();
44 
45 	SERVICE_SELECT(SERVICE_VM1, "boot_memory_overrun", mb.send);
46 
47 	run_res = ffa_run(SERVICE_VM1, 0);
48 	EXPECT_FFA_ERROR(run_res, FFA_ABORTED);
49 }
50 
51 /**
52  * Accessing memory before the start of the image traps the VM and yields.
53  */
TEST(boot,memory_before_image)54 TEST(boot, memory_before_image)
55 {
56 	struct ffa_value run_res;
57 	struct mailbox_buffers mb = set_up_mailbox();
58 
59 	SERVICE_SELECT(SERVICE_VM1, "boot_memory_underrun", mb.send);
60 
61 	run_res = ffa_run(SERVICE_VM1, 0);
62 	EXPECT_FFA_ERROR(run_res, FFA_ABORTED);
63 }
64 
TEST(mem_permission,ffa_mem_get_test)65 TEST(mem_permission, ffa_mem_get_test)
66 {
67 	struct ffa_value res;
68 	struct mailbox_buffers mb = set_up_mailbox();
69 	SERVICE_SELECT(SERVICE_VM1, "ffa_mem_perm_get", mb.send);
70 
71 	/* Let the secondary get started and wait for a message. */
72 	res = ffa_run(SERVICE_VM1, 0);
73 	EXPECT_EQ(res.func, FFA_MSG_WAIT_32);
74 	EXPECT_EQ(res.arg2, FFA_SLEEP_INDEFINITE);
75 
76 	/*
77 	 * Send direct message to tell service VM to do FFA_MEM_PERM_GET tests.
78 	 */
79 	res = ffa_msg_send_direct_req(HF_PRIMARY_VM_ID, SERVICE_VM1, 1, 0, 0, 0,
80 				      0);
81 	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
82 
83 	/* Check that VM's cannot use this ABI */
84 	res = ffa_mem_perm_get(0xDEADBEEF);
85 	EXPECT_EQ(res.func, FFA_ERROR_32);
86 	EXPECT_EQ(ffa_error_code(res), FFA_DENIED);
87 }
88 
TEST(mem_permission,ffa_mem_set_test)89 TEST(mem_permission, ffa_mem_set_test)
90 {
91 	struct ffa_value res;
92 	struct mailbox_buffers mb = set_up_mailbox();
93 	SERVICE_SELECT(SERVICE_VM1, "ffa_mem_perm_set", mb.send);
94 
95 	/* Let the secondary get started and wait for a message. */
96 	res = ffa_run(SERVICE_VM1, 0);
97 	EXPECT_EQ(res.func, FFA_MSG_WAIT_32);
98 	EXPECT_EQ(res.arg2, FFA_SLEEP_INDEFINITE);
99 
100 	res = ffa_msg_send_direct_req(HF_PRIMARY_VM_ID, SERVICE_VM1, 1, 0, 0, 0,
101 				      0);
102 	EXPECT_EQ(res.func, FFA_MSG_SEND_DIRECT_RESP_32);
103 
104 	/* Check that VM's cannot use this ABI */
105 	res = ffa_mem_perm_set(0xDEADBEEF, 0x1000, 0xf);
106 	EXPECT_EQ(res.func, FFA_ERROR_32);
107 	EXPECT_EQ(ffa_error_code(res), FFA_DENIED);
108 }
109