blob: f8cefa5c76a4343f2b10413aeed432580f9ba509 [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/**
Andrew Scull33fecd32019-01-08 14:48:27 +000040 * Encode a preempted response without leaking.
41 */
42TEST(abi, hf_vcpu_run_return_encode_preempted)
43{
44 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
45 res.code = HF_VCPU_RUN_PREEMPTED;
46 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0));
47}
48
49/**
50 * Decode a preempted response ignoring the irrelevant bits.
51 */
52TEST(abi, hf_vcpu_run_return_decode_preempted)
53{
54 struct hf_vcpu_run_return res =
55 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b00);
56 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_PREEMPTED));
57}
58
59/**
Andrew Scull6d2db332018-10-10 15:28:17 +010060 * Encode a yield response without leaking.
61 */
62TEST(abi, hf_vcpu_run_return_encode_yield)
63{
64 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
65 res.code = HF_VCPU_RUN_YIELD;
Andrew Scull33fecd32019-01-08 14:48:27 +000066 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(1));
Andrew Scull6d2db332018-10-10 15:28:17 +010067}
68
69/**
70 * Decode a yield response ignoring the irrelevant bits.
71 */
72TEST(abi, hf_vcpu_run_return_decode_yield)
73{
74 struct hf_vcpu_run_return res =
Andrew Scull33fecd32019-01-08 14:48:27 +000075 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b01);
Andrew Scull6d2db332018-10-10 15:28:17 +010076 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_YIELD));
77}
78
79/**
80 * Encode wait-for-interrupt response without leaking.
81 */
82TEST(abi, hf_vcpu_run_return_encode_wait_for_interrupt)
83{
84 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
85 res.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT;
Andrew Scullb06d1752019-02-04 10:15:48 +000086 res.sleep.ns = HF_SLEEP_INDEFINITE;
87 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xffffffffffffff02));
88}
89
90/**
91 * Encoding wait-for-interrupt response with too large sleep duration will drop
92 * the top octet.
93 */
94TEST(abi, hf_vcpu_run_return_encode_wait_for_interrupt_sleep_too_long)
95{
96 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
97 res.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT;
98 res.sleep.ns = 0xcc22888888888888;
99 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x2288888888888802));
Andrew Scull6d2db332018-10-10 15:28:17 +0100100}
101
102/**
103 * Decode a wait-for-interrupt response ignoring the irrelevant bits.
104 */
105TEST(abi, hf_vcpu_run_return_decode_wait_for_interrupt)
106{
107 struct hf_vcpu_run_return res =
Andrew Scull33fecd32019-01-08 14:48:27 +0000108 hf_vcpu_run_return_decode(0x1234abcdbadb0102);
Andrew Scull6d2db332018-10-10 15:28:17 +0100109 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAIT_FOR_INTERRUPT));
Andrew Scullb06d1752019-02-04 10:15:48 +0000110 EXPECT_THAT(res.sleep.ns, Eq(0x1234abcdbadb01));
111}
112
113/**
114 * Encode wait-for-message response without leaking.
115 */
116TEST(abi, hf_vcpu_run_return_encode_wait_for_message)
117{
118 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
119 res.code = HF_VCPU_RUN_WAIT_FOR_MESSAGE;
120 res.sleep.ns = HF_SLEEP_INDEFINITE;
121 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xffffffffffffff03));
122}
123
124/**
125 * Encoding wait-for-message response with too large sleep duration will drop
126 * the top octet.
127 */
128TEST(abi, hf_vcpu_run_return_encode_wait_for_message_sleep_too_long)
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 = 0xaa99777777777777;
133 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x9977777777777703));
134}
135
136/**
137 * Decode a wait-for-message response ignoring the irrelevant bits.
138 */
139TEST(abi, hf_vcpu_run_return_decode_wait_for_message)
140{
141 struct hf_vcpu_run_return res =
142 hf_vcpu_run_return_decode(0x12347654badb0103);
143 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAIT_FOR_MESSAGE));
144 EXPECT_THAT(res.sleep.ns, Eq(0x12347654badb01));
Andrew Scull6d2db332018-10-10 15:28:17 +0100145}
146
147/**
148 * Encode wake up response without leaking.
149 */
150TEST(abi, hf_vcpu_run_return_encode_wake_up)
151{
152 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
153 res.code = HF_VCPU_RUN_WAKE_UP;
154 res.wake_up.vm_id = 0x12345678;
155 res.wake_up.vcpu = 0xabcd;
Andrew Scullb06d1752019-02-04 10:15:48 +0000156 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x12345678abcd0004));
Andrew Scull6d2db332018-10-10 15:28:17 +0100157}
158
159/**
160 * Decode a wake up response ignoring the irrelevant bits.
161 */
162TEST(abi, hf_vcpu_run_return_decode_wake_up)
163{
164 struct hf_vcpu_run_return res =
Andrew Scullb06d1752019-02-04 10:15:48 +0000165 hf_vcpu_run_return_decode(0xbeefd00df00daf04);
Andrew Scull6d2db332018-10-10 15:28:17 +0100166 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAKE_UP));
167 EXPECT_THAT(res.wake_up.vm_id, Eq(0xbeefd00d));
168 EXPECT_THAT(res.wake_up.vcpu, Eq(0xf00d));
169}
170
171/**
172 * Encode message response without leaking.
173 */
174TEST(abi, hf_vcpu_run_return_encode_message)
175{
176 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
177 res.code = HF_VCPU_RUN_MESSAGE;
178 res.message.size = 0xdeadbeef;
Andrew Scullb06d1752019-02-04 10:15:48 +0000179 res.message.vm_id = 0xf007;
180 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xdeadbeeff0070005));
Andrew Scull6d2db332018-10-10 15:28:17 +0100181}
182
183/**
184 * Decode a wake up response ignoring the irrelevant bits.
185 */
186TEST(abi, hf_vcpu_run_return_decode_message)
187{
188 struct hf_vcpu_run_return res =
Andrew Scullb06d1752019-02-04 10:15:48 +0000189 hf_vcpu_run_return_decode(0x1123581314916205);
Andrew Scull6d2db332018-10-10 15:28:17 +0100190 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_MESSAGE));
191 EXPECT_THAT(res.message.size, Eq(0x11235813));
Andrew Scullb06d1752019-02-04 10:15:48 +0000192 EXPECT_THAT(res.message.vm_id, Eq(0x1491));
Andrew Scull6d2db332018-10-10 15:28:17 +0100193}
194
195/**
Andrew Scull9726c252019-01-23 13:44:19 +0000196 * Encode a 'notify waiters' response without leaking.
197 */
198TEST(abi, hf_vcpu_run_return_encode_notify_waiters)
199{
200 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
201 res.code = HF_VCPU_RUN_NOTIFY_WAITERS;
202 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(6));
203}
204
205/**
206 * Decode a 'notify waiters' response ignoring the irrelevant bits.
207 */
208TEST(abi, hf_vcpu_run_return_decode_notify_waiters)
209{
210 struct hf_vcpu_run_return res =
211 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b06);
212 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_NOTIFY_WAITERS));
213}
214
215/**
216 * Encode an aborted response without leaking.
217 */
218TEST(abi, hf_vcpu_run_return_encode_aborted)
219{
220 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
221 res.code = HF_VCPU_RUN_ABORTED;
222 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(7));
223}
224
225/**
226 * Decode an aborted response ignoring the irrelevant bits.
227 */
228TEST(abi, hf_vcpu_run_return_decode_aborted)
229{
230 struct hf_vcpu_run_return res =
231 hf_vcpu_run_return_decode(0x31dbac4810fbc507);
232 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_ABORTED));
233}
234
Andrew Scull6d2db332018-10-10 15:28:17 +0100235} /* namespace */