xref: /openbsd/usr.sbin/vmd/virtio.h (revision 55cc5ba3)
1 /*	$OpenBSD: virtio.h,v 1.36 2021/01/07 17:11:38 tracey 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 
212 	int idx;
213 	int lockedmac;
214 	int local;
215 	int pxeboot;
216 
217 	uint8_t pci_id;
218 };
219 
220 struct virtio_net_hdr {
221 	uint8_t flags;
222 	uint8_t gso_type;
223 	uint16_t hdr_len;
224 	uint16_t gso_size;
225 	uint16_t csum_start;
226 	uint16_t csum_offset;
227 
228 	/*
229 	 * num_buffers is only used if VIRTIO_NET_F_MRG_RXBUF is negotiated.
230 	 * vmd(8) doesn't negotiate that, but the field is listed here
231 	 * for completeness sake.
232 	 */
233 /*	uint16_t num_buffers; */
234 };
235 
236 enum vmmci_cmd {
237 	VMMCI_NONE = 0,
238 	VMMCI_SHUTDOWN,
239 	VMMCI_REBOOT,
240 	VMMCI_SYNCRTC,
241 };
242 
243 struct vmmci_dev {
244 	struct virtio_io_cfg cfg;
245 	struct event timeout;
246 	struct timeval time;
247 	enum vmmci_cmd cmd;
248 	uint32_t vm_id;
249 	int irq;
250 
251 	uint8_t pci_id;
252 };
253 
254 struct ioinfo {
255 	struct virtio_backing *file;
256 	uint8_t *buf;
257 	ssize_t len;
258 	off_t offset;
259 	int error;
260 };
261 
262 /* virtio.c */
263 void virtio_init(struct vmd_vm *, int, int[][VM_MAX_BASE_PER_DISK], int *);
264 void virtio_shutdown(struct vmd_vm *);
265 int virtio_dump(int);
266 int virtio_restore(int, struct vmd_vm *, int,
267     int[][VM_MAX_BASE_PER_DISK], int *);
268 uint32_t vring_size(uint32_t);
269 
270 int virtio_rnd_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
271 int viornd_dump(int);
272 int viornd_restore(int, struct vm_create_params *);
273 void viornd_update_qs(void);
274 void viornd_update_qa(void);
275 int viornd_notifyq(void);
276 
277 ssize_t virtio_qcow2_get_base(int, char *, size_t, const char *);
278 int virtio_qcow2_create(const char *, const char *, long);
279 int virtio_qcow2_init(struct virtio_backing *, off_t *, int*, size_t);
280 int virtio_raw_create(const char *, long);
281 int virtio_raw_init(struct virtio_backing *, off_t *, int*, size_t);
282 
283 int virtio_blk_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
284 int vioblk_dump(int);
285 int vioblk_restore(int, struct vmop_create_params *,
286     int[][VM_MAX_BASE_PER_DISK]);
287 void vioblk_update_qs(struct vioblk_dev *);
288 void vioblk_update_qa(struct vioblk_dev *);
289 int vioblk_notifyq(struct vioblk_dev *);
290 
291 int virtio_net_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
292 int vionet_dump(int);
293 int vionet_restore(int, struct vmd_vm *, int *);
294 void vionet_update_qs(struct vionet_dev *);
295 void vionet_update_qa(struct vionet_dev *);
296 int vionet_notifyq(struct vionet_dev *);
297 void vionet_notify_rx(struct vionet_dev *);
298 int vionet_notify_tx(struct vionet_dev *);
299 void vionet_process_rx(uint32_t);
300 int vionet_enq_rx(struct vionet_dev *, char *, ssize_t, int *);
301 
302 int vmmci_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
303 int vmmci_dump(int);
304 int vmmci_restore(int, uint32_t);
305 int vmmci_ctl(unsigned int);
306 void vmmci_ack(unsigned int);
307 void vmmci_timeout(int, short, void *);
308 
309 const char *vioblk_cmd_name(uint32_t);
310 int vioscsi_dump(int);
311 int vioscsi_restore(int, struct vm_create_params *, int);
312 
313 /* dhcp.c */
314 ssize_t dhcp_request(struct vionet_dev *, char *, size_t, char **);
315 
316 /* vioscsi.c */
317 int vioscsi_io(int, uint16_t, uint32_t *, uint8_t *, void *, uint8_t);
318 void vioscsi_update_qs(struct vioscsi_dev *);
319 void vioscsi_update_qa(struct vioscsi_dev *);
320 int vioscsi_notifyq(struct vioscsi_dev *);
321 void virtio_stop(struct vm_create_params *vcp);
322 void virtio_start(struct vm_create_params *vcp);
323