blob: 12dde09194e2f101c36b15c8472af9905abd1d3f [file] [log] [blame]
Andrew Scull6d2db332018-10-10 15:28:17 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull6d2db332018-10-10 15:28:17 +01003 *
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 * https://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
17extern "C" {
18#include "vmapi/hf/abi.h"
19}
20
21#include <gmock/gmock.h>
22
23namespace
24{
25using ::testing::Eq;
26
27/**
28 * Simulate an uninitialized hf_vcpu_run_return so it can be detected if any
29 * uninitialized fields make their way into the encoded form which would
30 * indicate a data leak.
31 */
32struct hf_vcpu_run_return dirty_vcpu_run_return()
33{
34 struct hf_vcpu_run_return res;
35 memset(&res, 0xc5, sizeof(res));
36 return res;
37}
38
39/**
40 * Simulate an uninitialized hf_mailbox_receive_return so it can be detected if
41 * any uninitialized fields make their way into the encoded form which would
42 * indicate a data leak.
43 */
44struct hf_mailbox_receive_return dirty_mailbox_receive_return()
45{
46 struct hf_mailbox_receive_return res;
47 memset(&res, 0xc5, sizeof(res));
48 return res;
49}
50
51/**
Andrew Scull33fecd32019-01-08 14:48:27 +000052 * Encode a preempted response without leaking.
53 */
54TEST(abi, hf_vcpu_run_return_encode_preempted)
55{
56 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
57 res.code = HF_VCPU_RUN_PREEMPTED;
58 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0));
59}
60
61/**
62 * Decode a preempted response ignoring the irrelevant bits.
63 */
64TEST(abi, hf_vcpu_run_return_decode_preempted)
65{
66 struct hf_vcpu_run_return res =
67 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b00);
68 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_PREEMPTED));
69}
70
71/**
Andrew Scull6d2db332018-10-10 15:28:17 +010072 * Encode a yield response without leaking.
73 */
74TEST(abi, hf_vcpu_run_return_encode_yield)
75{
76 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
77 res.code = HF_VCPU_RUN_YIELD;
Andrew Scull33fecd32019-01-08 14:48:27 +000078 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(1));
Andrew Scull6d2db332018-10-10 15:28:17 +010079}
80
81/**
82 * Decode a yield response ignoring the irrelevant bits.
83 */
84TEST(abi, hf_vcpu_run_return_decode_yield)
85{
86 struct hf_vcpu_run_return res =
Andrew Scull33fecd32019-01-08 14:48:27 +000087 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b01);
Andrew Scull6d2db332018-10-10 15:28:17 +010088 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_YIELD));
89}
90
91/**
92 * Encode wait-for-interrupt response without leaking.
93 */
94TEST(abi, hf_vcpu_run_return_encode_wait_for_interrupt)
95{
96 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
97 res.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT;
Andrew Scullb06d1752019-02-04 10:15:48 +000098 res.sleep.ns = HF_SLEEP_INDEFINITE;
99 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xffffffffffffff02));
100}
101
102/**
103 * Encoding wait-for-interrupt response with too large sleep duration will drop
104 * the top octet.
105 */
106TEST(abi, hf_vcpu_run_return_encode_wait_for_interrupt_sleep_too_long)
107{
108 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
109 res.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT;
110 res.sleep.ns = 0xcc22888888888888;
111 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x2288888888888802));
Andrew Scull6d2db332018-10-10 15:28:17 +0100112}
113
114/**
115 * Decode a wait-for-interrupt response ignoring the irrelevant bits.
116 */
117TEST(abi, hf_vcpu_run_return_decode_wait_for_interrupt)
118{
119 struct hf_vcpu_run_return res =
Andrew Scull33fecd32019-01-08 14:48:27 +0000120 hf_vcpu_run_return_decode(0x1234abcdbadb0102);
Andrew Scull6d2db332018-10-10 15:28:17 +0100121 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAIT_FOR_INTERRUPT));
Andrew Scullb06d1752019-02-04 10:15:48 +0000122 EXPECT_THAT(res.sleep.ns, Eq(0x1234abcdbadb01));
123}
124
125/**
126 * Encode wait-for-message response without leaking.
127 */
128TEST(abi, hf_vcpu_run_return_encode_wait_for_message)
129{
130 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
131 res.code = HF_VCPU_RUN_WAIT_FOR_MESSAGE;
132 res.sleep.ns = HF_SLEEP_INDEFINITE;
133 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xffffffffffffff03));
134}
135
136/**
137 * Encoding wait-for-message response with too large sleep duration will drop
138 * the top octet.
139 */
140TEST(abi, hf_vcpu_run_return_encode_wait_for_message_sleep_too_long)
141{
142 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
143 res.code = HF_VCPU_RUN_WAIT_FOR_MESSAGE;
144 res.sleep.ns = 0xaa99777777777777;
145 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x9977777777777703));
146}
147
148/**
149 * Decode a wait-for-message response ignoring the irrelevant bits.
150 */
151TEST(abi, hf_vcpu_run_return_decode_wait_for_message)
152{
153 struct hf_vcpu_run_return res =
154 hf_vcpu_run_return_decode(0x12347654badb0103);
155 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAIT_FOR_MESSAGE));
156 EXPECT_THAT(res.sleep.ns, Eq(0x12347654badb01));
Andrew Scull6d2db332018-10-10 15:28:17 +0100157}
158
159/**
160 * Encode wake up response without leaking.
161 */
162TEST(abi, hf_vcpu_run_return_encode_wake_up)
163{
164 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
165 res.code = HF_VCPU_RUN_WAKE_UP;
166 res.wake_up.vm_id = 0x12345678;
167 res.wake_up.vcpu = 0xabcd;
Andrew Scullb06d1752019-02-04 10:15:48 +0000168 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x12345678abcd0004));
Andrew Scull6d2db332018-10-10 15:28:17 +0100169}
170
171/**
172 * Decode a wake up response ignoring the irrelevant bits.
173 */
174TEST(abi, hf_vcpu_run_return_decode_wake_up)
175{
176 struct hf_vcpu_run_return res =
Andrew Scullb06d1752019-02-04 10:15:48 +0000177 hf_vcpu_run_return_decode(0xbeefd00df00daf04);
Andrew Scull6d2db332018-10-10 15:28:17 +0100178 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAKE_UP));
179 EXPECT_THAT(res.wake_up.vm_id, Eq(0xbeefd00d));
180 EXPECT_THAT(res.wake_up.vcpu, Eq(0xf00d));
181}
182
183/**
184 * Encode message response without leaking.
185 */
186TEST(abi, hf_vcpu_run_return_encode_message)
187{
188 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
189 res.code = HF_VCPU_RUN_MESSAGE;
190 res.message.size = 0xdeadbeef;
Andrew Scullb06d1752019-02-04 10:15:48 +0000191 res.message.vm_id = 0xf007;
192 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xdeadbeeff0070005));
Andrew Scull6d2db332018-10-10 15:28:17 +0100193}
194
195/**
196 * Decode a wake up response ignoring the irrelevant bits.
197 */
198TEST(abi, hf_vcpu_run_return_decode_message)
199{
200 struct hf_vcpu_run_return res =
Andrew Scullb06d1752019-02-04 10:15:48 +0000201 hf_vcpu_run_return_decode(0x1123581314916205);
Andrew Scull6d2db332018-10-10 15:28:17 +0100202 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_MESSAGE));
203 EXPECT_THAT(res.message.size, Eq(0x11235813));
Andrew Scullb06d1752019-02-04 10:15:48 +0000204 EXPECT_THAT(res.message.vm_id, Eq(0x1491));
Andrew Scull6d2db332018-10-10 15:28:17 +0100205}
206
207/**
Andrew Scull9726c252019-01-23 13:44:19 +0000208 * Encode a 'notify waiters' response without leaking.
209 */
210TEST(abi, hf_vcpu_run_return_encode_notify_waiters)
211{
212 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
213 res.code = HF_VCPU_RUN_NOTIFY_WAITERS;
214 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(6));
215}
216
217/**
218 * Decode a 'notify waiters' response ignoring the irrelevant bits.
219 */
220TEST(abi, hf_vcpu_run_return_decode_notify_waiters)
221{
222 struct hf_vcpu_run_return res =
223 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b06);
224 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_NOTIFY_WAITERS));
225}
226
227/**
228 * Encode an aborted response without leaking.
229 */
230TEST(abi, hf_vcpu_run_return_encode_aborted)
231{
232 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
233 res.code = HF_VCPU_RUN_ABORTED;
234 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(7));
235}
236
237/**
238 * Decode an aborted response ignoring the irrelevant bits.
239 */
240TEST(abi, hf_vcpu_run_return_decode_aborted)
241{
242 struct hf_vcpu_run_return res =
243 hf_vcpu_run_return_decode(0x31dbac4810fbc507);
244 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_ABORTED));
245}
246
247/**
Andrew Scull6d2db332018-10-10 15:28:17 +0100248 * Encode a mailbox receive response without leaking.
249 */
250TEST(abi, hf_mailbox_receive_return_encode)
251{
252 struct hf_mailbox_receive_return res = dirty_mailbox_receive_return();
253 res.vm_id = 0x12345678;
254 res.size = 0xaabbccdd;
255 EXPECT_THAT(hf_mailbox_receive_return_encode(res),
256 Eq(0xaabbccdd12345678));
257}
258
259/**
260 * Decode a mailbox receive response.
261 */
262TEST(abi, hf_mailbox_receive_return_decode)
263{
264 struct hf_mailbox_receive_return res =
265 hf_mailbox_receive_return_decode(0X8badf00d00ddba11);
266 EXPECT_THAT(res.vm_id, Eq(0X00ddba11));
267 EXPECT_THAT(res.size, Eq(0x8badf00d));
268}
269
Andrew Scull6d2db332018-10-10 15:28:17 +0100270} /* namespace */