1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "testing/HostAddressSpace.h"
15
16 #include "aemu/base/AlignedBuf.h"
17 #include "host-common/GraphicsAgentFactory.h"
18 #include "host-common/address_space_device.h"
19 #include "host-common/address_space_device.hpp"
20 #include "host-common/testing/MockGraphicsAgentFactory.h"
21
22 #include <gtest/gtest.h>
23
24 namespace android {
25
26 class HostAddressSpaceTest : public ::testing::Test {
27 protected:
SetUpTestSuite()28 static void SetUpTestSuite() {
29 android::emulation::injectGraphicsAgents(
30 android::emulation::MockGraphicsAgentFactory());
31 emulation::goldfish_address_space_set_vm_operations(getGraphicsAgents()->vm);
32 }
33
TearDownTestSuite()34 static void TearDownTestSuite() { }
35
SetUp()36 void SetUp() override {
37 mDevice = HostAddressSpaceDevice::get();
38 }
39
TearDown()40 void TearDown() override {
41 if (mDevice) mDevice->clear();
42 // mDevice is singleton, no need to tear down
43 }
44 HostAddressSpaceDevice* mDevice = nullptr;
45 };
46
47 // Tests the constructor.
TEST_F(HostAddressSpaceTest,Basic)48 TEST_F(HostAddressSpaceTest, Basic) { }
49
50 // Tests open/close.
TEST_F(HostAddressSpaceTest,OpenClose)51 TEST_F(HostAddressSpaceTest, OpenClose) {
52 uint32_t handle = mDevice->open();
53 EXPECT_NE(0, handle);
54 mDevice->close(handle);
55 }
56
57 // Tests host interface existing
TEST_F(HostAddressSpaceTest,FunctionPointers)58 TEST_F(HostAddressSpaceTest, FunctionPointers) {
59 EXPECT_NE(nullptr,
60 get_address_space_device_hw_funcs());
61 EXPECT_NE(nullptr,
62 get_address_space_device_hw_funcs()->allocSharedHostRegion);
63 EXPECT_NE(nullptr,
64 get_address_space_device_hw_funcs()->allocSharedHostRegionLocked);
65 EXPECT_NE(nullptr,
66 get_address_space_device_hw_funcs()->freeSharedHostRegion);
67 EXPECT_NE(nullptr,
68 get_address_space_device_hw_funcs()->freeSharedHostRegionLocked);
69 EXPECT_NE(nullptr,
70 get_address_space_device_hw_funcs()->getPhysAddrStart);
71 EXPECT_NE(nullptr,
72 get_address_space_device_hw_funcs()->getPhysAddrStartLocked);
73 }
74
75 // Tests allocation and freeing of host shared regions.
TEST_F(HostAddressSpaceTest,HostSharedAllocs)76 TEST_F(HostAddressSpaceTest, HostSharedAllocs) {
77 auto hwFuncs = get_address_space_device_hw_funcs();
78
79 // Test that passing nullptr as the offset results in an error.
80 int allocRes = hwFuncs->allocSharedHostRegion(4096, nullptr);
81
82 EXPECT_EQ(-EINVAL, allocRes);
83
84 uint64_t offset;
85 allocRes = hwFuncs->allocSharedHostRegion(4096, &offset);
86
87 EXPECT_EQ(0, allocRes);
88
89 int freeRes = hwFuncs->freeSharedHostRegion(offset);
90
91 EXPECT_EQ(0, freeRes);
92
93 freeRes = hwFuncs->freeSharedHostRegion(offset);
94
95 EXPECT_EQ(-EINVAL, freeRes);
96 }
97
98 // Tests the interface to get the starting phys addr.
TEST_F(HostAddressSpaceTest,HostGetStartingPhysAddr)99 TEST_F(HostAddressSpaceTest, HostGetStartingPhysAddr) {
100 auto hwFuncs = get_address_space_device_hw_funcs();
101 auto physStart = hwFuncs->getPhysAddrStart();
102 EXPECT_NE(0, physStart);
103 }
104
105 // Tests host interface APIs Locked* versions.
TEST_F(HostAddressSpaceTest,HostInterfaceLocked)106 TEST_F(HostAddressSpaceTest, HostInterfaceLocked) {
107 auto hwFuncs = get_address_space_device_hw_funcs();
108
109 // Test that passing nullptr as the offset results in an error.
110 int allocRes = hwFuncs->allocSharedHostRegionLocked(4096, nullptr);
111
112 EXPECT_EQ(-EINVAL, allocRes);
113
114 uint64_t offset;
115 allocRes = hwFuncs->allocSharedHostRegionLocked(4096, &offset);
116
117 EXPECT_EQ(0, allocRes);
118
119 int freeRes = hwFuncs->freeSharedHostRegionLocked(offset);
120
121 EXPECT_EQ(0, freeRes);
122
123 freeRes = hwFuncs->freeSharedHostRegionLocked(offset);
124
125 EXPECT_EQ(-EINVAL, freeRes);
126
127 auto physStart = hwFuncs->getPhysAddrStartLocked();
128 EXPECT_NE(0, physStart);
129 }
130
131 // Tests claiming/unclaiming shared regions.
132 // Test that two different handles can share the same offset.
TEST_F(HostAddressSpaceTest,SharedRegionClaiming)133 TEST_F(HostAddressSpaceTest, SharedRegionClaiming) {
134 auto hwFuncs = get_address_space_device_hw_funcs();
135 uint32_t handle = mDevice->open();
136 uint32_t handle2 = mDevice->open();
137
138 EXPECT_NE(0, handle);
139
140 uint64_t offset;
141 int allocRes = hwFuncs->allocSharedHostRegion(4096, &offset);
142 EXPECT_EQ(0, allocRes);
143
144 int claimRes = mDevice->claimShared(handle, offset, 4096);
145 EXPECT_EQ(0, claimRes);
146 claimRes = mDevice->claimShared(handle2, offset, 4096);
147 EXPECT_EQ(0, claimRes);
148
149 int unclaimRes = mDevice->unclaimShared(handle, offset);
150 EXPECT_EQ(0, unclaimRes);
151 unclaimRes = mDevice->unclaimShared(handle2, offset);
152 EXPECT_EQ(0, unclaimRes);
153
154 int freeRes = hwFuncs->freeSharedHostRegion(offset);
155 EXPECT_EQ(0, freeRes);
156
157 mDevice->close(handle);
158 mDevice->close(handle2);
159 }
160
161 // Tests error cases when claiming/unclaiming shared regions;
162 // a region must have been created via allocSharedHostRegionLocked,
163 // and the same offset cannot be claimed or unclaimed twice with the same handle.
TEST_F(HostAddressSpaceTest,SharedRegionClaimingNegative)164 TEST_F(HostAddressSpaceTest, SharedRegionClaimingNegative) {
165 auto hwFuncs = get_address_space_device_hw_funcs();
166 uint32_t handle = mDevice->open();
167
168 EXPECT_NE(0, handle);
169
170 uint64_t offset;
171 int allocRes = hwFuncs->allocSharedHostRegion(4096, &offset);
172 EXPECT_EQ(0, allocRes);
173
174 int claimRes = mDevice->claimShared(handle, offset - 1, 4096);
175 EXPECT_EQ(-EINVAL, claimRes);
176 claimRes = mDevice->claimShared(handle, offset, 4097);
177 EXPECT_EQ(-EINVAL, claimRes);
178 claimRes = mDevice->claimShared(handle, offset, 4096);
179 EXPECT_EQ(0, claimRes);
180 claimRes = mDevice->claimShared(handle, offset, 4096);
181 EXPECT_EQ(-EINVAL, claimRes);
182
183 int unclaimRes = mDevice->unclaimShared(handle, offset + 1);
184 EXPECT_EQ(-EINVAL, unclaimRes);
185 unclaimRes = mDevice->unclaimShared(handle, offset - 1);
186 EXPECT_EQ(-EINVAL, unclaimRes);
187 unclaimRes = mDevice->unclaimShared(handle, offset);
188 EXPECT_EQ(0, unclaimRes);
189 unclaimRes = mDevice->unclaimShared(handle, offset);
190 EXPECT_EQ(-EINVAL, unclaimRes);
191
192 int freeRes = hwFuncs->freeSharedHostRegion(offset);
193 EXPECT_EQ(0, freeRes);
194
195 mDevice->close(handle);
196 }
197
198 // Tests the HVA association API.
TEST_F(HostAddressSpaceTest,HostAddressMapping)199 TEST_F(HostAddressSpaceTest, HostAddressMapping) {
200 auto hwFuncs = get_address_space_device_hw_funcs();
201 auto buf = aligned_buf_alloc(4096, 4096);
202 uint32_t handle = mDevice->open();
203
204 EXPECT_NE(0, handle);
205
206 uint64_t offset;
207 int allocRes = hwFuncs->allocSharedHostRegion(4096, &offset);
208 EXPECT_EQ(0, allocRes);
209
210 uint64_t physAddr = hwFuncs->getPhysAddrStart() + offset;
211 mDevice->setHostAddrByPhysAddr(physAddr, buf);
212
213 EXPECT_EQ(buf, mDevice->getHostAddr(physAddr));
214
215 int claimRes = mDevice->claimShared(handle, offset, 4096);
216 EXPECT_EQ(0, claimRes);
217
218 int unclaimRes = mDevice->unclaimShared(handle, offset);
219 EXPECT_EQ(0, unclaimRes);
220
221 int freeRes = hwFuncs->freeSharedHostRegion(offset);
222 EXPECT_EQ(0, freeRes);
223
224 aligned_buf_free(buf);
225 mDevice->close(handle);
226 }
227
228 } // namespace android
229