-
Notifications
You must be signed in to change notification settings - Fork 4
/
libkvmchan-priv.h
237 lines (201 loc) · 7 KB
/
libkvmchan-priv.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
/**
* Copyright 2018-2021 Shawn Anastasio
*
* This file is part of libkvmchan.
*
* libkvmchan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libkvmchan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libkvmchan. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LIBKVMCHAN_PRIV_H
#define LIBKVMCHAN_PRIV_H
#include <stdint.h>
#include <stdbool.h>
#include <ringbuf.h>
// Base path for run-time sockets/config
#define RUNTIME_BASE_DIR "/var/run/kvmchand"
// Socket path used by ivshmem server
#define IVSHMEM_SOCK_PATH (RUNTIME_BASE_DIR "/ivshmem_socket")
// Socket path used by kvmchand localhandler
#define LOCALHANDLER_SOCK_PATH (RUNTIME_BASE_DIR "/localhandler_socket")
/* client<->kvmchand API */
#define KVMCHAND_API_VERSION 1
#define KVMCHAND_MSG_NUM_ARGS 4
/**
* A message sent from a client (API consumer) to kvmchand.
*/
struct kvmchand_message {
uint64_t command;
/**
* Confirm client<->kvmchand communication works.
*
* ret - (i64) API version number supported by host
*/
#define KVMCHAND_CMD_HELLO 0
/**
* Create a new vchan.
* args[0] - (u32) domain # of client
* args[1] - (u32) port
* args[2] - (u64) read_min
* args[3] - (u64) write_min
*
* Note: In some cases it may not be possible to immediately return
* all connection fds. In this case, ret will not indicate an error but
* the fd count will be 0 and the user must request the fds at a later time
* using KVMCHAND_CMD_GET_CONN_FDS.
*
* ret - (u32) The IVPosition of the new ivshmem device, or 0 if called from dom0.
* fds_count - 5
* fds - vchan shmfd, incoming eventfds 0-1, outgoing eventfds 0-1
*/
#define KVMCHAND_CMD_SERVERINIT 1
/**
* Connect to an existing vchan.
* args[0] - (u32) domain # of server
* args[1] - (u32) port
*
* Note: In some cases it may not be possible to immediately return
* all connection fds. In this case, ret will not indicate an error but
* the fd count will be 0 and the user must request the fds at a later time
* using KVMCHAND_CMD_GET_CONN_FDS.
*
* ret - (u32) The IVPosition of the ivshmem device, or 0 if called from dom0.
* fds_count - 5
* fds - vchan shmfd, incoming eventfds 0-1, outgoing eventfds 0-1
*/
#define KVMCHAND_CMD_CLIENTINIT 2
/**
* Get connection fds for an existing vchan/shmem
* args[0] - (u32) IVPosition of the ivshmem device backing the requested vchan
* args[1] - (bool) only memfd?
*
* fds_count - only_memfd ? 1 : 5
* fds - vchan shmfd, (!only_memfd) incoming eventfds 0-1, (!only_memfd) outgoing eventfds 0-1
*/
#define KVMCHAND_CMD_GET_CONN_FDS 3
/**
* Close an existing vchan.
* args[0] - (u32) domain # of client
* args[1] - (u32) port
*/
#define KVMCHAND_CMD_CLOSE 4
/**
* Register a client disconnect on a vchan.
* args[0] - (u32) domain # of server
* args[1] - (u32) port
*/
#define KVMCHAND_CMD_CLIENT_DISCONNECT 5
/**
* Get the state of a vchan (client's perspective)
* args[0] - (u32) domain # of server
* args[1] - (u32) port
*
* ret - (int) VCHAN_{DISCONNECTED,CONNECTED,WAITING}
*/
#define KVMCHAND_CMD_GET_STATE_CLIENT 6
/**
* Get the state of a vchan (server's perspective)
* args[0] - (u32) domain # of client
* args[1] - (u32) port
*
* ret - (int) VCHAN_{DISCONNECTED,CONNECTED,WAITING}
*/
#define KVMCHAND_CMD_GET_STATE_SERVER 7
/**
* Create an shmem region for sharing with a given client dom.
* args[0] - (u32) domain # of client
* args[1] - (u32) local page size (overridden by localhandler)
* args[2] - (size_t) page count
*
* Note: In some cases it may not be possible to immediately return
* all connection fds. In this case, ret will not indicate an error but
* the fd count will be 0 and the user must request the fds at a later time
* using KVMCHAND_CMD_GET_CONN_FDS.
*
* ret - (u64) ((u32)ivposition_or_0 << 32 | (u32)region_id)
* ret2 - (size_t) start_offset
* fd_count - 1
* fds - backing shmfd
*/
#define KVMCHAND_CMD_SHMEM_CREATE 8
/**
* Close an existing shmem region (server).
* args[0] - (u32) domain # of client
* args[1] - (u32) region id
*/
#define KVMCHAND_CMD_SHMEM_CLOSE 9
/**
* Connect to an existing shmem region.
* args[0] - (u32) domain # of server
* args[1] - (u32) region id
* args[2] - (u32) local page size (overriden by localhandler)
*
* ret - (u32) ivposition_or_0
* ret2 - (size_t) start_offset
* fd_count - 1
* fds - backing shmfd
*/
#define KVMCHAND_CMD_SHMEM_CONN 10
/**
* Close a previously opened shmem region (client).
* args[0] - (u32) domain # of server
* args[1] - (u32) region id
*/
#define KVMCHAND_CMD_SHMEM_CLIENT_DISCONNECT 11
int64_t args[KVMCHAND_MSG_NUM_ARGS];
};
/**
* A response sent from kvmchand to a client
*/
struct kvmchand_ret {
int64_t ret;
int64_t ret2;
bool error;
// Error codes, stored in `ret` when `error` is true
#define KVMCHAND_ERR_FAILURE 0 // Generic failure
#define KVMCHAND_ERR_DOMOFFLINE 1 // Domain offline
uint8_t fd_count; // Number of file descriptors returned
#define KVMCHAND_FD_MAX 5
};
/**
* Header placed at start of every shared memory region
*/
#define SHMEM_MAGIC 0xDEADBEEFCAFEBABA
typedef struct shmem_hdr {
uint64_t magic;
ringbuf_pub_t host_to_client_pub;
ringbuf_pub_t client_to_host_pub;
} shmem_hdr_t;
/* Maximum ring size (512MB). Chosen arbitrarily */
#define MAX_RING_SIZE 0x20000000
/* Size of SHM region between client and kvmchand */
#define DAEMON_SHM_SIZE 0x100000
/* Size of rbs shared between client and kvmchand */
#define DAEMON_RING_SIZE ((DAEMON_SHM_SIZE - sizeof(shmem_hdr_t)) / 2)
/* Offsets of rbs in shm region between client and kvmchand */
#define DAEMON_H2C_OFFSET (sizeof(shmem_hdr_t))
#define DAEMON_C2H_OFFSET (DAEMON_H2C_OFFSET + DAEMON_RING_SIZE)
/* IVPosition for ivshmem device used for guest<->host kvmchand communication */
#define KVMCHAND_IVPOSITION 1
/* Number of eventfds for each direction */
#define NUM_EVENTFDS 2
/* Macros */
// Ignore unused variable/return warnings.
// Especially for eventfd actions that can't fail.
// This macro was taken from gnulib.
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
# define ignore_value(x) \
(__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
#else
# define ignore_value(x) ((void) (x))
#endif
#endif // LIBKVMCHAN_PRIV_H