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