xref: /openbsd/usr.sbin/vmd/virtio.h (revision d89ec533)
1 /*	$OpenBSD: virtio.h,v 1.41 2021/07/16 16:21:22 dv Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <dev/pv/virtioreg.h>
22 #include <net/if_tun.h>
23 
24 #include <event.h>
25 
26 #include "vmd.h"
27 
28 #ifndef _VIRTIO_H_
29 #define _VIRTIO_H_
30 
31 #define VIRTQUEUE_ALIGN(n)	(((n)+(VIRTIO_PAGE_SIZE-1))&    \
32 				    ~(VIRTIO_PAGE_SIZE-1))
33 #define ALIGNSZ(sz, align)	((sz + align - 1) & ~(align - 1))
34 #define MIN(a,b)		(((a)<(b))?(a):(b))
35 
36 /* Queue sizes must be power of two */
37 #define VIORND_QUEUE_SIZE	64
38 #define VIORND_QUEUE_MASK	(VIORND_QUEUE_SIZE - 1)
39 
40 #define VIOBLK_QUEUE_SIZE	128
41 #define VIOBLK_QUEUE_MASK	(VIOBLK_QUEUE_SIZE - 1)
42 
43 #define VIOSCSI_QUEUE_SIZE	128
44 #define VIOSCSI_QUEUE_MASK	(VIOSCSI_QUEUE_SIZE - 1)
45 
46 #define VIONET_QUEUE_SIZE	256
47 #define VIONET_QUEUE_MASK	(VIONET_QUEUE_SIZE - 1)
48 
49 /* Virtio network device is backed by tap(4), so inherit limits */
50 #define VIONET_HARD_MTU		TUNMRU
51 #define VIONET_MIN_TXLEN	ETHER_HDR_LEN
52 #define VIONET_MAX_TXLEN	VIONET_HARD_MTU + ETHER_HDR_LEN
53 
54 /* VMM Control Interface shutdown timeout (in seconds) */
55 #define VMMCI_TIMEOUT		3
56 #define VMMCI_SHUTDOWN_TIMEOUT	120
57 
58 /* All the devices we support have either 1, 2 or 3 queues */
59 /* viornd - 1 queue
60  * vioblk - 1 queue
61  * vionet - 2 queues
62  * vioscsi - 3 queues
63  */
64 #define VIRTIO_MAX_QUEUES	3
65 
66 /*
67  * This struct stores notifications from a virtio driver. There is
68  * one such struct per virtio device.
69  */
70 struct virtio_io_cfg {
71 	uint32_t device_feature;
72 	uint32_t guest_feature;
73 	uint32_t queue_address;
74 	uint16_t queue_size;
75 	uint16_t queue_select;
76 	uint16_t queue_notify;
77 	uint8_t device_status;
78 	uint8_t isr_status;
79 };
80 
81 struct virtio_backing {
82 	void  *p;
83 	ssize_t  (*pread)(void *p, char *buf, size_t len, off_t off);
84 	ssize_t  (*pwrite)(void *p, char *buf, size_t len, off_t off);
85 	void (*close)(void *p, int);
86 };
87 
88 /*
89  * A virtio device can have several virtqs. For example, vionet has one virtq
90  * each for transmitting and receiving packets. This struct describes the state
91  * of one virtq, such as their address in memory, size, offsets of rings, etc.
92  * There is one virtio_vq_info per virtq.
93  */
94 struct virtio_vq_info {
95 	/* Guest physical address of virtq */
96 	uint32_t qa;
97 
98 	/* Queue size: number of queue entries in virtq */
99 	uint32_t qs;
100 
101 	/*
102 	 * The offset of the 'available' ring within the virtq located at
103 	 * guest physical address qa above
104 	 */
105 	uint32_t vq_availoffset;
106 
107 	/*
108 	 * The offset of the 'used' ring within the virtq located at guest
109 	 * physical address qa above
110 	 */
111 	uint32_t vq_usedoffset;
112 
113 	/*
114 	 * The index into a slot of the 'available' ring that a virtio device
115 	 * can consume next
116 	 */
117 	uint16_t last_avail;
118 
119 	/*
120 	 * The most recent index into the 'available' ring that a virtio
121 	 * driver notified to the host.
122 	 */
123 	uint16_t notified_avail;
124 };
125 
126 /*
127  * Each virtio driver has a notifyq method where one or more messages
128  * are ready to be processed on a given virtq.  As such, various
129  * pieces of information are needed to provide ring accounting while
130  * processing a given message such as virtq indexes, vring pointers, and
131  * vring descriptors.
132  */
133 struct virtio_vq_acct {
134 
135 	/* index of previous avail vring message */
136 	uint16_t idx;
137 
138 	/* index of current message containing the request */
139 	uint16_t req_idx;
140 
141 	/* index of current message containing the response */
142 	uint16_t resp_idx;
143 
144 	/* vring descriptor pointer */
145 	struct vring_desc *desc;
146 
147 	/* vring descriptor pointer for request header and data */
148 	struct vring_desc *req_desc;
149 
150 	/* vring descriptor pointer for response header and data */
151 	struct vring_desc *resp_desc;
152 
153 	/* pointer to the available vring */
154 	struct vring_avail *avail;
155 
156 	/* pointer to the used vring */
157 	struct vring_used *used;
158 };
159 
160 struct viornd_dev {
161 	struct virtio_io_cfg cfg;
162 
163 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
164 
165 	uint8_t pci_id;
166 	int irq;
167 	uint32_t vm_id;
168 };
169 
170 struct vioblk_dev {
171 	struct virtio_io_cfg cfg;
172 
173 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
174 	struct virtio_backing file;
175 
176 	uint64_t sz;
177 	uint32_t max_xfer;
178 
179 	uint8_t pci_id;
180 	int irq;
181 	uint32_t vm_id;
182 };
183 
184 /* vioscsi will use at least 3 queues - 5.6.2 Virtqueues
185  * Current implementation will use 3
186  * 0 - control
187  * 1 - event
188  * 2 - requests
189  */
190 struct vioscsi_dev {
191 	struct virtio_io_cfg cfg;
192 
193 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
194 
195 	struct virtio_backing file;
196 
197 	/* is the device locked */
198 	int locked;
199 	/* size of iso file in bytes */
200 	uint64_t sz;
201 	/* last block address read */
202 	uint64_t lba;
203 	/* number of blocks represented in iso */
204 	uint64_t n_blocks;
205 	uint32_t max_xfer;
206 
207 	uint8_t pci_id;
208 	uint32_t vm_id;
209 	int irq;
210 };
211 
212 struct vionet_dev {
213 	pthread_mutex_t mutex;
214 	struct event event;
215 
216 	struct virtio_io_cfg cfg;
217 
218 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
219 
220 	int fd;
221 	uint32_t vm_id;
222 	uint32_t vm_vmid;
223 	int irq;
224 	uint8_t mac[6];
225 	uint8_t hostmac[6];
226 
227 	int idx;
228 	int lockedmac;
229 	int local;
230 	int pxeboot;
231 
232 	uint8_t pci_id;
233 };
234 
235 struct virtio_net_hdr {
236 	uint8_t flags;
237 	uint8_t gso_type;
238 	uint16_t hdr_len;
239 	uint16_t gso_size;
240 	uint16_t csum_start;
241 	uint16_t csum_offset;
242 
243 	/*
244 	 * num_buffers is only used if VIRTIO_NET_F_MRG_RXBUF is negotiated.
245 	 * vmd(8) doesn't negotiate that, but the field is listed here
246 	 * for completeness sake.
247 	 */
248 /*	uint16_t num_buffers; */
249 };
250 
251 enum vmmci_cmd {
252 	VMMCI_NONE = 0,
253 	VMMCI_SHUTDOWN,
254 	VMMCI_REBOOT,
255 	VMMCI_SYNCRTC,
256 };
257 
258 struct vmmci_dev {
259 	struct virtio_io_cfg cfg;
260 	struct event timeout;
261 	struct timeval time;
262 	enum vmmci_cmd cmd;
263 	uint32_t vm_id;
264 	int irq;
265 
266 	uint8_t pci_id;
267 };
268 
269 struct ioinfo {
270 	struct virtio_backing *file;
271 	uint8_t *buf;
272 	ssize_t len;
273 	off_t offset;
274 	int error;
275 };
276 
277 /* virtio.c */
278 void virtio_init(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], int *);
279 void virtio_shutdown(struct vmd_vm *);
280 int virtio_dump(int);
281 int virtio_restore(int, struct vmd_vm *, int,
282     int[][VM_MAX_BASE_PER_DISK], int *);
283 uint32_t vring_size(uint32_t);
284 
285 int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
286 int viornd_dump(int);
287 int viornd_restore(int, struct vm_create_params *);
288 void viornd_update_qs(void);
289 void viornd_update_qa(void);
290 int viornd_notifyq(void);
291 
292 ssize_t virtio_qcow2_get_base(int, char *, size_t, const char *);
293 int virtio_qcow2_create(const char *, const char *, long);
294 int virtio_qcow2_init(struct virtio_backing *, off_t *, int*, size_t);
295 int virtio_raw_create(const char *, long);
296 int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t);
297 
298 int virtio_blk_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
299 int vioblk_dump(int);
300 int vioblk_restore(int, struct vmop_create_params *,
301     int[][VM_MAX_BASE_PER_DISK]);
302 void vioblk_update_qs(struct vioblk_dev *);
303 void vioblk_update_qa(struct vioblk_dev *);
304 int vioblk_notifyq(struct vioblk_dev *);
305 
306 int virtio_net_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
307 int vionet_dump(int);
308 int vionet_restore(int, struct vmd_vm *, int *);
309 void vionet_update_qs(struct vionet_dev *);
310 void vionet_update_qa(struct vionet_dev *);
311 int vionet_notifyq(struct vionet_dev *);
312 void vionet_notify_rx(struct vionet_dev *);
313 int vionet_notify_tx(struct vionet_dev *);
314 void vionet_process_rx(uint32_t);
315 int vionet_enq_rx(struct vionet_dev *, char *, size_t, int *);
316 void vionet_set_hostmac(struct vmd_vm *, unsigned int, uint8_t *);
317 
318 int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
319 int vmmci_dump(int);
320 int vmmci_restore(int, uint32_t);
321 int vmmci_ctl(unsigned int);
322 void vmmci_ack(unsigned int);
323 void vmmci_timeout(int, short, void *);
324 
325 const char *vioblk_cmd_name(uint32_t);
326 int vioscsi_dump(int);
327 int vioscsi_restore(int, struct vm_create_params *, int);
328 
329 /* dhcp.c */
330 ssize_t dhcp_request(struct vionet_dev *, char *, size_t, char **);
331 
332 /* vioscsi.c */
333 int vioscsi_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
334 void vioscsi_update_qs(struct vioscsi_dev *);
335 void vioscsi_update_qa(struct vioscsi_dev *);
336 int vioscsi_notifyq(struct vioscsi_dev *);
337 void virtio_stop(struct vm_create_params *vcp);
338 void virtio_start(struct vm_create_params *vcp);
339 
340 #endif /* _VIRTIO_H_ */
341