This repository has been archived by the owner on Jan 4, 2024. It is now read-only.
forked from Solo5/solo5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hvt.h
240 lines (206 loc) · 7.25 KB
/
hvt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
* Copyright (c) 2015-2018 Contributors as noted in the AUTHORS file
*
* This file is part of Solo5, a sandboxed execution environment.
*
* Permission to use, copy, modify, and/or distribute this software
* for any purpose with or without fee is hereby granted, provided
* that the above copyright notice and this permission notice appear
* in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* hvt.h: hvt tender internal API definitions.
*
* Architecture and backend-independent users should not need to include any
* other header files.
*/
#ifndef HVT_H
#define HVT_H
#include <inttypes.h>
#include <err.h>
#include "cc.h"
#define HVT_HOST
#include "hvt_abi.h"
#include "hvt_gdb.h"
/*
* HVT_DROP_PRIVILEGES (1) enables the function hvt_drop_privileges
* please see hvt_drop_privileges for more information
* HCT_DROP_PRIVILEGES would be disabled in a debugging scenario
* where the hvt has to create/modify files outside it normal operating domain
*/
#ifndef HVT_DROP_PRIVILEGES
#define HVT_DROP_PRIVILEGES 1
#endif
/*
* Hypervisor {arch,backend}-independent data is defined here.
* {arch,backend}-dependent data (b) is defined in hvt_{backend}.h.
*/
struct hvt {
uint8_t *mem;
size_t mem_size;
struct hvt_b *b;
};
/*
* Load an ELF binary from (file) into (mem_size) bytes of (mem), returning
* the entry point (gpa_ep) and last byte used by the binary (gpa_kend).
*/
void hvt_elf_load(const char *file, uint8_t *mem, size_t mem_size,
hvt_gpa_t *p_entry, hvt_gpa_t *p_end);
/*
* Check that (gpa) and (gpa + sz) are within guest memory. Returns a host-side
* pointer to (gpa) if successful, aborts if not.
*/
#define HVT_CHECKED_GPA_P(hvt, gpa, sz) \
hvt_checked_gpa_p((hvt), (gpa), (sz), __FILE__, __LINE__)
inline void *hvt_checked_gpa_p(struct hvt *hvt, hvt_gpa_t gpa, size_t sz,
const char *file, int line)
{
hvt_gpa_t r;
if ((gpa >= hvt->mem_size) || add_overflow(gpa, sz, r) ||
(r >= hvt->mem_size)) {
errx(1, "%s:%d: Invalid guest access: gpa=0x%" PRIx64 ", sz=%zu",
file, line, gpa, sz);
}
else {
return (void *)(hvt->mem + gpa);
}
}
/*
* Initialise hypervisor, with (mem_size) bytes of guest memory.
* (hvt->mem) and (hvt->mem_size) are valid after this function has been called.
*/
struct hvt *hvt_init(size_t mem_size);
/*
* Computes the memory size to use for this tender, based on the user-provided
* value (rounding down if necessary).
*/
void hvt_mem_size(size_t *mem_size);
/*
* Initialise VCPU state with (gpa_ep) as the entry point and (gpa_kend) as the
* last byte of memory used by the guest binary. In (*cmdline), returns a
* buffer with HVT_CMDLINE_SIZE bytes of space for the guest command line.
*/
void hvt_vcpu_init(struct hvt *hvt, hvt_gpa_t gpa_ep,
hvt_gpa_t gpa_kend, char **cmdline);
#if HVT_DROP_PRIVILEGES
/*
* Drop privileges. This function is called by the tender before entering the
* VCPU loop, after guest memory has been set up and all host resources have
* been acquired. Backend implementations SHOULD drop privileges to the minimum
* required to run the guest at this point.
*/
void hvt_drop_privileges();
#endif
/*
* Run the VCPU. Returns on normal guest exit. Returns the exit status passed
* from the unikernel on the final exit.
*/
int hvt_vcpu_loop(struct hvt *hvt);
/*
* Register the file descriptor (fd) for use with HVT_HYPERCALL_POLL.
*/
int hvt_core_register_pollfd(int fd);
/*
* Register (fn) as the handler for hypercall (nr).
*/
typedef void (*hvt_hypercall_fn_t)(struct hvt *hvt, hvt_gpa_t gpa);
int hvt_core_register_hypercall(int nr, hvt_hypercall_fn_t fn);
/*
* Register (fn) as a hook for HVT_HYPERCALL_HALT.
*/
typedef void (*hvt_halt_fn_t)(struct hvt *hvt, int status, void *cookie);
int hvt_core_register_halt_hook(hvt_halt_fn_t fn);
/*
* Dispatch array of [HVT_HYPERCALL_MAX] hypercalls. NULL = no handler.
*/
extern hvt_hypercall_fn_t hvt_core_hypercalls[];
int hvt_core_hypercall_halt(struct hvt *hvt, hvt_gpa_t gpa);
/*
* Register a custom vmexit handler (fn). (fn) must return 0 if the vmexit was
* handled, -1 if not.
*/
typedef int (*hvt_vmexit_fn_t)(struct hvt *hvt);
int hvt_core_register_vmexit(hvt_vmexit_fn_t fn);
/*
* Dispatch array of module-registered vmexit handlers. NULL terminated.
*/
extern hvt_vmexit_fn_t hvt_core_vmexits[];
/*
* Module definition. (name) and (setup) are required, all other functions are
* optional.
*/
struct hvt_module {
const char *name;
int (*setup)(struct hvt *hvt);
int (*handle_cmdarg)(char *cmdarg);
char *(*usage)(void);
};
/*
* Array of compiled-in modules. NULL terminated.
*/
extern struct hvt_module *hvt_core_modules[];
extern struct hvt_module hvt_module_core;
extern struct hvt_module hvt_module_blk;
extern struct hvt_module hvt_module_net;
extern struct hvt_module hvt_module_gdb;
extern struct hvt_module hvt_module_dumpcore;
/*
* GDB specific functions to be implemented on all backends for all
* architectures.
*/
/*
* Check if backend implements GDB support. Returns 0 if supported, -1 if not.
* Note backends not implementing GDB support still need to implement the
* remaining functions in this section, all of which should return -1.
*/
int hvt_gdb_supported(void);
/*
* Fills *reg with a stream of hexadecimal digits for each guest register
* in GDB register order, where each register is in target endian order.
* Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_read_registers(struct hvt *hvt, uint8_t *reg, size_t *len);
/*
* Writes all guest registers from a stream of hexadecimal digits for each
* register in *reg. Each register in *reg is in GDB register order, and in
* target endian order.
* Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_write_registers(struct hvt *hvt, uint8_t *reg, size_t len);
/*
* Enable single stepping. Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_enable_ss(struct hvt *hvt);
/*
* Disable single stepping. Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_disable_ss(struct hvt *hvt);
/*
* Reads the current KVM exit code and maps it to a GDB signal value.
* Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_read_last_signal(struct hvt *hvt, int *signal);
/*
* Add a breakpoint of type software or hardware, at address addr. len is
* typically the size of the breakpoint in bytes that should be inserted
* Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_add_breakpoint(struct hvt *hvt, gdb_breakpoint_type type,
hvt_gpa_t addr, size_t len);
/*
* Remove a breakpoint of type software or hardware, at address addr. len is
* typically the size of the breakpoint in bytes that should be inserted.
* Returns 0 if success, -1 otherwise.
*/
int hvt_gdb_remove_breakpoint(struct hvt *hvt, gdb_breakpoint_type type,
hvt_gpa_t addr, size_t len);
#endif /* HVT_H */