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