xref: /openbsd/usr.sbin/vmd/virtio.h (revision c4fd4c5b)
1 /*	$OpenBSD: virtio.h,v 1.52 2024/07/10 09:27:33 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 and less than IOV_MAX (1024). */
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 #define VIOBLK_SEG_MAX		(VIOBLK_QUEUE_SIZE - 2)
43 
44 #define VIOSCSI_QUEUE_SIZE	128
45 #define VIOSCSI_QUEUE_MASK	(VIOSCSI_QUEUE_SIZE - 1)
46 
47 #define VIONET_QUEUE_SIZE	256
48 #define VIONET_QUEUE_MASK	(VIONET_QUEUE_SIZE - 1)
49 
50 /* Virtio network device is backed by tap(4), so inherit limits */
51 #define VIONET_HARD_MTU		TUNMRU
52 #define VIONET_MIN_TXLEN	ETHER_HDR_LEN
53 #define VIONET_MAX_TXLEN	VIONET_HARD_MTU + ETHER_HDR_LEN
54 
55 /* VMM Control Interface shutdown timeout (in seconds) */
56 #define VMMCI_TIMEOUT		3
57 #define VMMCI_SHUTDOWN_TIMEOUT	120
58 
59 /* All the devices we support have either 1, 2 or 3 queues */
60 /* viornd - 1 queue
61  * vioblk - 1 queue
62  * vionet - 2 queues
63  * vioscsi - 3 queues
64  */
65 #define VIRTIO_MAX_QUEUES	3
66 
67 #define MAXPHYS	(64 * 1024)	/* max raw I/O transfer size */
68 
69 /*
70  * Rename the address config register to be more descriptive.
71  */
72 #define VIRTIO_CONFIG_QUEUE_PFN	VIRTIO_CONFIG_QUEUE_ADDRESS
73 #define DEVICE_NEEDS_RESET	VIRTIO_CONFIG_DEVICE_STATUS_DEVICE_NEEDS_RESET
74 #define DESC_WRITABLE(/* struct vring_desc */ x)	\
75 	(((x)->flags & VRING_DESC_F_WRITE) ? 1 : 0)
76 
77 
78 /*
79  * VM <-> Device messaging.
80  */
81 struct viodev_msg {
82 	uint8_t type;
83 #define VIODEV_MSG_INVALID	0
84 #define VIODEV_MSG_READY	1
85 #define VIODEV_MSG_ERROR	2
86 #define VIODEV_MSG_KICK		3
87 #define VIODEV_MSG_IO_READ	4
88 #define VIODEV_MSG_IO_WRITE	5
89 #define VIODEV_MSG_DUMP		6
90 #define VIODEV_MSG_SHUTDOWN	7
91 
92 	uint16_t reg;		/* VirtIO register */
93 	uint8_t io_sz;		/* IO instruction size */
94 	uint8_t vcpu;		/* VCPU id */
95 	uint8_t irq;		/* IRQ number */
96 
97 	int8_t state;		/* Interrupt state toggle (if any) */
98 #define INTR_STATE_ASSERT	 1
99 #define INTR_STATE_NOOP		 0
100 #define INTR_STATE_DEASSERT	-1
101 
102 	uint32_t data;		/* Data (if any) */
103 	uint8_t data_valid;	/* 1 if data field is populated. */
104 } __packed;
105 
106 /*
107  * This struct stores notifications from a virtio driver. There is
108  * one such struct per virtio device.
109  */
110 struct virtio_io_cfg {
111 	uint32_t device_feature;
112 	uint32_t guest_feature;
113 	uint32_t queue_pfn;
114 	uint16_t queue_size;
115 	uint16_t queue_select;
116 	uint16_t queue_notify;
117 	uint8_t device_status;
118 	uint8_t isr_status;
119 };
120 
121 struct virtio_backing {
122 	void  *p;
123 	ssize_t (*pread)(void *, char *, size_t, off_t);
124 	ssize_t (*preadv)(void *, struct iovec *, int, off_t);
125 	ssize_t (*pwrite)(void *, char *, size_t, off_t);
126 	ssize_t (*pwritev)(void *, struct iovec *, int, off_t);
127 	void (*close)(void *, int);
128 };
129 
130 /*
131  * A virtio device can have several virtqs. For example, vionet has one virtq
132  * each for transmitting and receiving packets. This struct describes the state
133  * of one virtq, such as their address in memory, size, offsets of rings, etc.
134  * There is one virtio_vq_info per virtq.
135  */
136 struct virtio_vq_info {
137 	/* Guest physical address of virtq */
138 	uint64_t q_gpa;
139 
140 	/* Host virtual address of virtq */
141 	void *q_hva;
142 
143 	/* Queue size: number of queue entries in virtq */
144 	uint32_t qs;
145 
146 	/*
147 	 * The offset of the 'available' ring within the virtq located at
148 	 * guest physical address qa above
149 	 */
150 	uint32_t vq_availoffset;
151 
152 	/*
153 	 * The offset of the 'used' ring within the virtq located at guest
154 	 * physical address qa above
155 	 */
156 	uint32_t vq_usedoffset;
157 
158 	/*
159 	 * The index into a slot of the 'available' ring that a virtio device
160 	 * can consume next
161 	 */
162 	uint16_t last_avail;
163 
164 	/*
165 	 * The most recent index into the 'available' ring that a virtio
166 	 * driver notified to the host.
167 	 */
168 	uint16_t notified_avail;
169 };
170 
171 /*
172  * Each virtio driver has a notifyq method where one or more messages
173  * are ready to be processed on a given virtq.  As such, various
174  * pieces of information are needed to provide ring accounting while
175  * processing a given message such as virtq indexes, vring pointers, and
176  * vring descriptors.
177  */
178 struct virtio_vq_acct {
179 
180 	/* index of previous avail vring message */
181 	uint16_t idx;
182 
183 	/* index of current message containing the request */
184 	uint16_t req_idx;
185 
186 	/* index of current message containing the response */
187 	uint16_t resp_idx;
188 
189 	/* vring descriptor pointer */
190 	struct vring_desc *desc;
191 
192 	/* vring descriptor pointer for request header and data */
193 	struct vring_desc *req_desc;
194 
195 	/* vring descriptor pointer for response header and data */
196 	struct vring_desc *resp_desc;
197 
198 	/* pointer to the available vring */
199 	struct vring_avail *avail;
200 
201 	/* pointer to the used vring */
202 	struct vring_used *used;
203 };
204 
205 struct viornd_dev {
206 	struct virtio_io_cfg cfg;
207 
208 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
209 
210 	uint8_t pci_id;
211 	int irq;
212 	uint32_t vm_id;
213 };
214 
215 struct vioblk_dev {
216 	struct virtio_io_cfg cfg;
217 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
218 	struct virtio_backing file;
219 
220 	int disk_fd[VM_MAX_BASE_PER_DISK];	/* fds for disk image(s) */
221 	uint8_t ndisk_fd;	/* number of valid disk fds */
222 	uint64_t capacity;	/* size in 512 byte sectors */
223 	uint32_t seg_max;	/* maximum number of segments */
224 
225 	unsigned int idx;
226 };
227 
228 /* vioscsi will use at least 3 queues - 5.6.2 Virtqueues
229  * Current implementation will use 3
230  * 0 - control
231  * 1 - event
232  * 2 - requests
233  */
234 struct vioscsi_dev {
235 	struct virtio_io_cfg cfg;
236 
237 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
238 
239 	struct virtio_backing file;
240 
241 	/* is the device locked */
242 	int locked;
243 	/* size of iso file in bytes */
244 	uint64_t sz;
245 	/* last block address read */
246 	uint64_t lba;
247 	/* number of blocks represented in iso */
248 	uint64_t n_blocks;
249 	uint32_t max_xfer;
250 
251 	uint8_t pci_id;
252 	uint32_t vm_id;
253 	int irq;
254 };
255 
256 struct vionet_dev {
257 	struct virtio_io_cfg cfg;
258 	struct virtio_vq_info vq[VIRTIO_MAX_QUEUES];
259 
260 	int data_fd;		/* fd for our tap device */
261 
262 	uint8_t mac[6];
263 	uint8_t hostmac[6];
264 	int lockedmac;
265 	int local;
266 	int pxeboot;
267 	struct local_prefix local_prefix;
268 
269 	unsigned int idx;
270 };
271 
272 struct virtio_dev {
273 	union {
274 		struct vioblk_dev vioblk;
275 		struct vionet_dev vionet;
276 	};
277 
278 	struct imsgev async_iev;
279 	struct imsgev sync_iev;
280 
281 	int sync_fd;		/* fd for synchronous channel */
282 	int async_fd;		/* fd for async channel */
283 
284 	uint8_t pci_id;
285 	uint32_t vm_id;
286 	uint32_t vm_vmid;
287 	int irq;
288 
289 	pid_t dev_pid;
290 	char dev_type;
291 	SLIST_ENTRY(virtio_dev) dev_next;
292 };
293 
294 struct virtio_net_hdr {
295 	uint8_t flags;
296 	uint8_t gso_type;
297 	uint16_t hdr_len;
298 	uint16_t gso_size;
299 	uint16_t csum_start;
300 	uint16_t csum_offset;
301 
302 	/*
303 	 * num_buffers is only used if VIRTIO_NET_F_MRG_RXBUF is negotiated.
304 	 * vmd(8) doesn't negotiate that, but the field is listed here
305 	 * for completeness sake.
306 	 */
307 /*	uint16_t num_buffers; */
308 };
309 
310 enum vmmci_cmd {
311 	VMMCI_NONE = 0,
312 	VMMCI_SHUTDOWN,
313 	VMMCI_REBOOT,
314 	VMMCI_SYNCRTC,
315 };
316 
317 struct vmmci_dev {
318 	struct virtio_io_cfg cfg;
319 	struct event timeout;
320 	struct timeval time;
321 	enum vmmci_cmd cmd;
322 	uint32_t vm_id;
323 	int irq;
324 
325 	uint8_t pci_id;
326 };
327 
328 /* XXX to be removed once vioscsi is adapted to vectorized io. */
329 struct ioinfo {
330 	uint8_t *buf;
331 	ssize_t len;
332 	off_t offset;
333 };
334 
335 /* virtio.c */
336 void virtio_init(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], int *);
337 void virtio_broadcast_imsg(struct vmd_vm *, uint16_t, void *, uint16_t);
338 void virtio_stop(struct vmd_vm *);
339 void virtio_start(struct vmd_vm *);
340 void virtio_shutdown(struct vmd_vm *);
341 int virtio_dump(int);
342 int virtio_restore(int, struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK],
343     int *);
344 const char *virtio_reg_name(uint8_t);
345 uint32_t vring_size(uint32_t);
346 int vm_device_pipe(struct virtio_dev *, void (*)(int, short, void *),
347     struct event_base *);
348 int virtio_pci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
349 void virtio_assert_irq(struct virtio_dev *, int);
350 void virtio_deassert_irq(struct virtio_dev *, int);
351 
352 int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
353 int viornd_dump(int);
354 int viornd_restore(int, struct vmd_vm *);
355 void viornd_update_qs(void);
356 void viornd_update_qa(void);
357 int viornd_notifyq(void);
358 
359 ssize_t virtio_qcow2_get_base(int, char *, size_t, const char *);
360 int virtio_qcow2_create(const char *, const char *, uint64_t);
361 int virtio_qcow2_init(struct virtio_backing *, off_t *, int*, size_t);
362 int virtio_raw_create(const char *, uint64_t);
363 int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t);
364 
365 int vioblk_dump(int);
366 int vioblk_restore(int, struct vmd_vm *, int[][VM_MAX_BASE_PER_DISK]);
367 
368 int vionet_dump(int);
369 int vionet_restore(int, struct vmd_vm *, int *);
370 void vionet_set_hostmac(struct vmd_vm *, unsigned int, uint8_t *);
371 
372 int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
373 int vmmci_dump(int);
374 int vmmci_restore(int, uint32_t);
375 int vmmci_ctl(unsigned int);
376 void vmmci_ack(unsigned int);
377 void vmmci_timeout(int, short, void *);
378 
379 const char *vioblk_cmd_name(uint32_t);
380 int vioscsi_dump(int);
381 int vioscsi_restore(int, struct vmd_vm *, int);
382 
383 /* dhcp.c */
384 ssize_t dhcp_request(struct virtio_dev *, char *, size_t, char **);
385 
386 /* vioscsi.c */
387 int vioscsi_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
388 void vioscsi_update_qs(struct vioscsi_dev *);
389 void vioscsi_update_qa(struct vioscsi_dev *);
390 int vioscsi_notifyq(struct vioscsi_dev *);
391 
392 #endif /* _VIRTIO_H_ */
393