1/*	$OpenBSD: virtio.h,v 1.51 2024/02/20 21:40:37 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 */
81struct 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 */
110struct 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
121struct 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 */
136struct 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 */
178struct 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
205struct 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
215struct 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 */
234struct 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
256struct 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
272struct 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
294struct 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
310enum vmmci_cmd {
311	VMMCI_NONE = 0,
312	VMMCI_SHUTDOWN,
313	VMMCI_REBOOT,
314	VMMCI_SYNCRTC,
315};
316
317struct 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. */
329struct ioinfo {
330	uint8_t *buf;
331	ssize_t len;
332	off_t offset;
333};
334
335/* virtio.c */
336void virtio_init(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], int *);
337void virtio_broadcast_imsg(struct vmd_vm *, uint16_t, void *, uint16_t);
338void virtio_stop(struct vmd_vm *);
339void virtio_start(struct vmd_vm *);
340void virtio_shutdown(struct vmd_vm *);
341int virtio_dump(int);
342int virtio_restore(int, struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK],
343    int *);
344const char *virtio_reg_name(uint8_t);
345uint32_t vring_size(uint32_t);
346int vm_device_pipe(struct virtio_dev *, void (*)(int, short, void *),
347    struct event_base *);
348int virtio_pci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
349void virtio_assert_pic_irq(struct virtio_dev *, int);
350void virtio_deassert_pic_irq(struct virtio_dev *, int);
351
352int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
353int viornd_dump(int);
354int viornd_restore(int, struct vmd_vm *);
355void viornd_update_qs(void);
356void viornd_update_qa(void);
357int viornd_notifyq(void);
358
359ssize_t virtio_qcow2_get_base(int, char *, size_t, const char *);
360int virtio_qcow2_create(const char *, const char *, uint64_t);
361int virtio_qcow2_init(struct virtio_backing *, off_t *, int*, size_t);
362int virtio_raw_create(const char *, uint64_t);
363int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t);
364
365int vioblk_dump(int);
366int vioblk_restore(int, struct vmd_vm *, int[][VM_MAX_BASE_PER_DISK]);
367
368int vionet_dump(int);
369int vionet_restore(int, struct vmd_vm *, int *);
370void vionet_set_hostmac(struct vmd_vm *, unsigned int, uint8_t *);
371
372int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
373int vmmci_dump(int);
374int vmmci_restore(int, uint32_t);
375int vmmci_ctl(unsigned int);
376void vmmci_ack(unsigned int);
377void vmmci_timeout(int, short, void *);
378
379const char *vioblk_cmd_name(uint32_t);
380int vioscsi_dump(int);
381int vioscsi_restore(int, struct vmd_vm *, int);
382
383/* dhcp.c */
384ssize_t dhcp_request(struct virtio_dev *, char *, size_t, char **);
385
386/* vioscsi.c */
387int vioscsi_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
388void vioscsi_update_qs(struct vioscsi_dev *);
389void vioscsi_update_qa(struct vioscsi_dev *);
390int vioscsi_notifyq(struct vioscsi_dev *);
391
392#endif /* _VIRTIO_H_ */
393