blob: d6bff21c2db05e67b0700221d4d1f376259e650c [file] [log] [blame]
Andrew Scull6d2db332018-10-10 15:28:17 +01001/*
2 * Copyright 2018 Google LLC
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 * 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/**
52 * Encode a yield response without leaking.
53 */
54TEST(abi, hf_vcpu_run_return_encode_yield)
55{
56 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
57 res.code = HF_VCPU_RUN_YIELD;
58 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0));
59}
60
61/**
62 * Decode a yield response ignoring the irrelevant bits.
63 */
64TEST(abi, hf_vcpu_run_return_decode_yield)
65{
66 struct hf_vcpu_run_return res =
67 hf_vcpu_run_return_decode(0x1a1a1a1a2b2b2b00);
68 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_YIELD));
69}
70
71/**
72 * Encode wait-for-interrupt response without leaking.
73 */
74TEST(abi, hf_vcpu_run_return_encode_wait_for_interrupt)
75{
76 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
77 res.code = HF_VCPU_RUN_WAIT_FOR_INTERRUPT;
78 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(1));
79}
80
81/**
82 * Decode a wait-for-interrupt response ignoring the irrelevant bits.
83 */
84TEST(abi, hf_vcpu_run_return_decode_wait_for_interrupt)
85{
86 struct hf_vcpu_run_return res =
87 hf_vcpu_run_return_decode(0x1234abcdbadb0101);
88 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAIT_FOR_INTERRUPT));
89}
90
91/**
92 * Encode wake up response without leaking.
93 */
94TEST(abi, hf_vcpu_run_return_encode_wake_up)
95{
96 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
97 res.code = HF_VCPU_RUN_WAKE_UP;
98 res.wake_up.vm_id = 0x12345678;
99 res.wake_up.vcpu = 0xabcd;
100 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x12345678abcd0002));
101}
102
103/**
104 * Decode a wake up response ignoring the irrelevant bits.
105 */
106TEST(abi, hf_vcpu_run_return_decode_wake_up)
107{
108 struct hf_vcpu_run_return res =
109 hf_vcpu_run_return_decode(0xbeefd00df00daf02);
110 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_WAKE_UP));
111 EXPECT_THAT(res.wake_up.vm_id, Eq(0xbeefd00d));
112 EXPECT_THAT(res.wake_up.vcpu, Eq(0xf00d));
113}
114
115/**
116 * Encode message response without leaking.
117 */
118TEST(abi, hf_vcpu_run_return_encode_message)
119{
120 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
121 res.code = HF_VCPU_RUN_MESSAGE;
122 res.message.size = 0xdeadbeef;
123 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xdeadbeef00000003));
124}
125
126/**
127 * Decode a wake up response ignoring the irrelevant bits.
128 */
129TEST(abi, hf_vcpu_run_return_decode_message)
130{
131 struct hf_vcpu_run_return res =
132 hf_vcpu_run_return_decode(0x1123581314916203);
133 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_MESSAGE));
134 EXPECT_THAT(res.message.size, Eq(0x11235813));
135}
136
137/**
138 * Encode sleep response without leaking.
139 */
140TEST(abi, hf_vcpu_run_return_encode_sleep)
141{
142 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
143 res.code = HF_VCPU_RUN_SLEEP;
144 res.sleep.ns = 0xcafed00dfeeded;
145 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0xcafed00dfeeded04));
146}
147
148/**
149 * Encoding a sleep response with too large a sleep duration will drop the top
150 * octet.
151 */
152TEST(abi, hf_vcpu_run_return_encode_sleep_too_long)
153{
154 struct hf_vcpu_run_return res = dirty_vcpu_run_return();
155 res.code = HF_VCPU_RUN_SLEEP;
156 res.sleep.ns = 0xcc88888888888888;
157 EXPECT_THAT(hf_vcpu_run_return_encode(res), Eq(0x8888888888888804));
158}
159
160/**
161 * Decode a sleep response.
162 */
163TEST(abi, hf_vcpu_run_return_decode_sleep)
164{
165 struct hf_vcpu_run_return res =
166 hf_vcpu_run_return_decode(0x1a2b3c4d5e6f7704);
167 EXPECT_THAT(res.code, Eq(HF_VCPU_RUN_SLEEP));
168 EXPECT_THAT(res.sleep.ns, Eq(0x1a2b3c4d5e6f77));
169}
170
171/**
172 * Encode a mailbox receive response without leaking.
173 */
174TEST(abi, hf_mailbox_receive_return_encode)
175{
176 struct hf_mailbox_receive_return res = dirty_mailbox_receive_return();
177 res.vm_id = 0x12345678;
178 res.size = 0xaabbccdd;
179 EXPECT_THAT(hf_mailbox_receive_return_encode(res),
180 Eq(0xaabbccdd12345678));
181}
182
183/**
184 * Decode a mailbox receive response.
185 */
186TEST(abi, hf_mailbox_receive_return_decode)
187{
188 struct hf_mailbox_receive_return res =
189 hf_mailbox_receive_return_decode(0X8badf00d00ddba11);
190 EXPECT_THAT(res.vm_id, Eq(0X00ddba11));
191 EXPECT_THAT(res.size, Eq(0x8badf00d));
192}
193
194} /* namespace */