include
vmcall_interface.h
Go to the documentation of this file.
1
/*
2
* Bareflank Hypervisor
3
*
4
* Copyright (C) 2015 Assured Information Security, Inc.
5
* Author: Rian Quinn <quinnr@ainfosec.com>
6
* Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7
*
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
23
#ifndef VMCALL_INTERFACE_H
24
#define VMCALL_INTERFACE_H
25
26
#pragma pack(push, 1)
27
28
#ifdef __cplusplus
29
extern
"C"
{
30
#endif
31
32
/*
33
* VMCall Magic Number
34
*
35
* Defines a magic number that can be defined by the user to uniquely identify
36
* both the version of the user as well as the VMM. Note that this value will
37
* change with each release of Bareflank, but should probably be manually set
38
* when creating production code.
39
*/
40
#ifndef VMCALL_MAGIC_NUMBER
41
#define VMCALL_MAGIC_NUMBER 0xB045EACDACD52E22
42
#endif
43
44
/*
45
* VMCall Version
46
*
47
* Define the version of this VMCall ABI. Note that unlike the magic number,
48
* this number only changes when this file changes.
49
*/
50
#define VMCALL_VERSION 1
51
52
/*
53
* VMCall Opcode
54
*
55
* Defines the vmcall being made. Note that these are generic vmcall opcodes,
56
* and they made be used to create actual commands to the hypervisor. For
57
* example, the registers vmcall could contain user defined instructions
58
* while the data vmcall could also contain JSON formatted instructions.
59
*
60
* Each opcode is defined below. Note that these might change as part of
61
* an updated. It's up to the user to ensure that versions match correctly.
62
*/
63
enum
vmcall_opcode
64
{
65
/*
66
* Versions
67
*
68
* Returns version information from the hypervisor which can be used by
69
* users of the vmcall interface to ensure that their code is compatible
70
* with the VMM.
71
*
72
* @note: indexes 0x0000000000000000 -> 0x7FFFFFFFFFFFFFFF are reserved
73
* for Bareflank. The remaining indexes may be used by custom
74
* extensions for version information
75
*
76
* In:
77
* r0 = VMCALL_VERSIONS
78
* r1 = VMCALL_MAGIC_NUMBER
79
* r2 = index
80
*
81
* Out (index == VMCALL_VERSION_PROTOCOL):
82
* r1 = 0 == success, error code otherwise
83
* r2 = index
84
* r3 = VMCALL_VERSION
85
*
86
* Out (index == VMCALL_VERSION_BAREFLANK):
87
* r1 = 0 == success, error code otherwise
88
* r2 = index
89
* r3 = BAREFLANK_VERSION_MAJOR
90
* r4 = BAREFLANK_VERSION_MINOR
91
* r5 = BAREFLANK_VERSION_PATCH
92
*
93
* Out (index == VMCALL_VERSION_USER):
94
* r1 = 0 == success, error code otherwise
95
* r2 = index
96
* r3 = USER_VERSION_MAJOR
97
* r4 = USER_VERSION_MINOR
98
* r5 = USER_VERSION_PATCH
99
*
100
* Out (index > 0x8000000000000000): User-defined
101
*/
102
VMCALL_VERSIONS
= 1,
103
104
/*
105
* Raw Registers
106
*
107
* Provides a means to send to the VMM, raw register values, and
108
* return raw register values. This is a wrapper around your basic vmcall,
109
* consuming the reserved registers in the process for ABI compatibility
110
*
111
* In:
112
* r0 = VMCALL_REGISTERS
113
* r1 = VMCALL_MAGIC_NUMBER
114
* r2 = xxx
115
* ...
116
* r31 = xxx
117
*
118
* Out:
119
* r1 = 0 == success, error code otherwise
120
* r2 = xxx
121
* ...
122
* r31 = xxx
123
*/
124
VMCALL_REGISTERS
= 2,
125
126
/*
127
* Data
128
*
129
* Provides a means to send and receive binary data (page sharing). With
130
* this vmcall, an in and out buffer are provided. The VMM will map in
131
* both buffers, perform whatever operation it should, and then unmap the
132
* buffers. The type field must be provided for the input buffer, and it
133
* defines what type of data is being provided. The VMM will return data
134
* in the output buffer, and set the output type based on whatever
135
* operation it performed. The size is in bytes, but the VMM will map
136
* complete pages. If the size of the buffer is not a multiple of a page,
137
* the VMM will have access to data outside the bounds of the buffer
138
* (which may be fine depending on the use case). The uuid field is provided
139
* as a means to identify the data being sent / received. Specifically,
140
* this field can be paired with the registers vmcall to ensure that
141
* consecutive vmcalls have the proper data. For example, if an operation
142
* takes more than one vmcall to perform, and software on the CPU is
143
* threaded, the uuid field provides the VMM with a means to handle when
144
* more than one vmcall becomes interlaced. Note that the uuid field is
145
* optional. out_size contains the max size of the output buffer that
146
* is provided, but the VMM must set out_size to the actual number of
147
* bytes that it is sending back, which likely will not be the same as
148
* the output buffer going in is likely the "max" sized buffer, while the
149
* actual contents being written back are likely smaller.
150
*
151
* In:
152
* r0 = VMCALL_DATA
153
* r1 = VMCALL_MAGIC_NUMBER
154
* r2 = uuid1 (bits 0 -> 63)
155
* r3 = uuid2 (bits 64 -> 127)
156
* r4 = in_type (vmcall_data_type)
157
* r5 = in_addr (addr of virtually contiguous buffer)
158
* r6 = in_size (size of virtually contiguous buffer)
159
* r7 = out_type (vmcall_data_type)
160
* r8 = out_addr (addr of virtually contiguous buffer)
161
* r9 = out_size (size of virtually contiguous buffer)
162
*
163
* Out:
164
* r1 = 0 == success, error code otherwise
165
*/
166
VMCALL_DATA
= 3,
167
168
/*
169
* Event
170
*
171
* This vmcall is used to signal and event (basically a virtual interrupt)
172
* Note that this takes a different path so it's faster than using
173
* VMCALL_REGISTERS as that call does more register copying. Also note
174
* that we provide for a success / failure on the event and it's up to the
175
* VMM extensions to decide if an event can actually fail.
176
*
177
* In:
178
* r0 = VMCALL_EVENT
179
* r1 = VMCALL_MAGIC_NUMBER
180
* r2 = index
181
*
182
* Out:
183
* r1 = 0 == success, error code otherwise
184
*/
185
VMCALL_EVENT
= 4,
186
187
/*
188
* Start
189
*
190
* This vmcall is used to run "start" code while the hypervisor is running.
191
* This vmcall should not be used by software and can only be used one
192
* by the bfdriver common.c
193
*
194
* In:
195
* r0 = VMCALL_START
196
* r1 = VMCALL_MAGIC_NUMBER
197
*
198
* Out:
199
* r1 = 0 == success, error code otherwise
200
*/
201
VMCALL_START
= 5,
202
203
/*
204
* Stop
205
*
206
* This vmcall is used to run "stop" code while the hypervisor is running.
207
* This vmcall should not be used by software and can only be used one
208
* by the bfdriver common.c
209
*
210
* In:
211
* r0 = VMCALL_STOP
212
* r1 = VMCALL_MAGIC_NUMBER
213
*
214
* Out:
215
* r1 = 0 == success, error code otherwise
216
*/
217
VMCALL_STOP
= 6,
218
219
/*
220
* Unit Test
221
*
222
* This vmcall is used to unit test software inside the VMM. For example,
223
* for Bareflank to ensure that supported portions of libc++ actually work
224
* inside the VMM, unit testing must be performed in the VMM itself. This
225
* vmcall does that.
226
*
227
* @note: indexes 0x0000000000000000 -> 0x7FFFFFFFFFFFFFFF are reserved
228
* for Bareflank. The remaining indexes may be used by custom
229
* extensions for their own unit tests
230
*
231
* In:
232
* r0 = VMCALL_UNITTEST
233
* r1 = VMCALL_MAGIC_NUMBER
234
* r2 = index
235
*
236
* Out:
237
* r1 = 0 == success, error code otherwise
238
*/
239
VMCALL_UNITTEST
= 10,
240
};
241
242
/*
243
* VMCall Versions
244
*
245
* Defines the different version indexes that are officially supported
246
* by Bareflank. Others may be used by the user as defined by the protocol
247
*
248
* @note: indexes 0x0000000000000000 -> 0x7FFFFFFFFFFFFFFF are reserved
249
* for Bareflank. The remaining indexes may be used by custom
250
* extensions to define their own version info
251
*/
252
enum
vmcall_versions
253
{
254
VMCALL_VERSION_PROTOCOL
= 0,
255
VMCALL_VERSION_BAREFLANK
= 1,
256
VMCALL_VERSION_USER
= 10,
257
};
258
259
/*
260
* VMCall Data Type
261
*
262
* Defines the different data types for data vmcall.
263
*
264
* @note: types 0x0000000000000000 -> 0x7FFFFFFFFFFFFFFF are reserved
265
* for Bareflank. The remaining types may be used by custom
266
* extensions to define their own data types
267
*/
268
enum
vmcall_data_type
269
{
270
VMCALL_DATA_NONE
= 0,
271
VMCALL_DATA_STRING_UNFORMATTED
= 1,
272
VMCALL_DATA_STRING_JSON
= 2,
273
VMCALL_DATA_BINARY_UNFORMATTED
= 10,
274
};
275
276
/*
277
* VMCall Registers
278
*
279
* Defines a structure that stores each register. The register names are
280
* generic so that they can be used by different CPU architectures.
281
*
282
* Intel: (unused: rsp, rbp, rdi)
283
* r0 = rax
284
* r1 = rdx
285
* r2 = rcx
286
* r3 = rdx
287
* r4 = rsi
288
* r5 = r8
289
* r6 = r9
290
* r7 = r10
291
* r8 = r11
292
* r9 = r12
293
* r10 = r13
294
* r11 = r14
295
* r12 = r15
296
* r13 = undefined
297
* ...
298
* r31 = undefined
299
*
300
* ARM:
301
* <TBD>
302
*/
303
struct
vmcall_registers_t
304
{
305
uintptr_t
r00
;
306
uintptr_t
r01
;
307
uintptr_t
r02
;
308
uintptr_t
r03
;
309
uintptr_t
r04
;
310
uintptr_t
r05
;
311
uintptr_t
r06
;
312
uintptr_t
r07
;
313
uintptr_t
r08
;
314
uintptr_t
r09
;
315
uintptr_t
r10
;
316
uintptr_t
r11
;
317
uintptr_t
r12
;
318
uintptr_t
r13
;
319
uintptr_t
r14
;
320
uintptr_t
r15
;
321
};
322
323
#ifdef __cplusplus
324
}
325
#endif
326
327
#pragma pack(pop)
328
329
#endif
vmcall_registers_t::r01
uintptr_t r01
Definition:
vmcall_interface.h:306
vmcall_registers_t
Definition:
vmcall_interface.h:303
VMCALL_DATA_NONE
Definition:
vmcall_interface.h:270
vmcall_registers_t::r08
uintptr_t r08
Definition:
vmcall_interface.h:313
VMCALL_VERSION_PROTOCOL
Definition:
vmcall_interface.h:254
vmcall_registers_t::r06
uintptr_t r06
Definition:
vmcall_interface.h:311
vmcall_registers_t::r15
uintptr_t r15
Definition:
vmcall_interface.h:320
VMCALL_DATA_STRING_JSON
Definition:
vmcall_interface.h:272
vmcall_registers_t::r12
uintptr_t r12
Definition:
vmcall_interface.h:317
VMCALL_EVENT
Definition:
vmcall_interface.h:185
vmcall_data_type
vmcall_data_type
Definition:
vmcall_interface.h:268
VMCALL_REGISTERS
Definition:
vmcall_interface.h:124
vmcall_registers_t::r10
uintptr_t r10
Definition:
vmcall_interface.h:315
VMCALL_DATA_STRING_UNFORMATTED
Definition:
vmcall_interface.h:271
vmcall_registers_t::r07
uintptr_t r07
Definition:
vmcall_interface.h:312
vmcall_registers_t::r05
uintptr_t r05
Definition:
vmcall_interface.h:310
vmcall_registers_t::r04
uintptr_t r04
Definition:
vmcall_interface.h:309
vmcall_registers_t::r00
uintptr_t r00
Definition:
vmcall_interface.h:305
VMCALL_STOP
Definition:
vmcall_interface.h:217
vmcall_registers_t::r02
uintptr_t r02
Definition:
vmcall_interface.h:307
VMCALL_DATA_BINARY_UNFORMATTED
Definition:
vmcall_interface.h:273
vmcall_opcode
vmcall_opcode
Definition:
vmcall_interface.h:63
VMCALL_DATA
Definition:
vmcall_interface.h:166
vmcall_registers_t::r14
uintptr_t r14
Definition:
vmcall_interface.h:319
VMCALL_VERSION_BAREFLANK
Definition:
vmcall_interface.h:255
vmcall_registers_t::r13
uintptr_t r13
Definition:
vmcall_interface.h:318
VMCALL_VERSION_USER
Definition:
vmcall_interface.h:256
VMCALL_VERSIONS
Definition:
vmcall_interface.h:102
VMCALL_UNITTEST
Definition:
vmcall_interface.h:239
VMCALL_START
Definition:
vmcall_interface.h:201
vmcall_registers_t::r09
uintptr_t r09
Definition:
vmcall_interface.h:314
vmcall_versions
vmcall_versions
Definition:
vmcall_interface.h:252
vmcall_registers_t::r11
uintptr_t r11
Definition:
vmcall_interface.h:316
vmcall_registers_t::r03
uintptr_t r03
Definition:
vmcall_interface.h:308
Generated on Fri Apr 28 2017 22:12:08 by
1.8.14