diff options
author | Laurent Vivier <lvivier@redhat.com> | 2022-11-08 21:16:46 +0100 |
---|---|---|
committer | Laurent Vivier <lvivier@redhat.com> | 2024-03-12 11:54:26 +0100 |
commit | 45b1403f42b70927ac859cee7c7413d5a596a671 (patch) | |
tree | 6f704609fb2274d3d0e766e730ffb322e6517a8a /virtio.h | |
parent | bb3877dde3d1403806092d121d64616c332a950c (diff) | |
download | passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar.gz passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar.bz2 passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar.lz passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar.xz passt-45b1403f42b70927ac859cee7c7413d5a596a671.tar.zst passt-45b1403f42b70927ac859cee7c7413d5a596a671.zip |
vhost-user: introduce virtio API
Add virtio.c and virtio.h that define the functions needed
to manage virtqueues.
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Diffstat (limited to 'virtio.h')
-rw-r--r-- | virtio.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/virtio.h b/virtio.h new file mode 100644 index 0000000..e334355 --- /dev/null +++ b/virtio.h @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +/* come parts copied from QEMU subprojects/libvhost-user/libvhost-user.h */ + +#ifndef VIRTIO_H +#define VIRTIO_H + +#include <stdbool.h> +#include <linux/vhost_types.h> + +#define VIRTQUEUE_MAX_SIZE 1024 + +#define vu_panic(vdev, ...) \ + do { \ + (vdev)->broken = true; \ + err( __VA_ARGS__ ); \ + } while (0) + +typedef struct VuRing { + unsigned int num; + struct vring_desc *desc; + struct vring_avail *avail; + struct vring_used *used; + uint64_t log_guest_addr; + uint32_t flags; +} VuRing; + +typedef struct VuVirtq { + VuRing vring; + + /* Next head to pop */ + uint16_t last_avail_idx; + + /* Last avail_idx read from VQ. */ + uint16_t shadow_avail_idx; + + uint16_t used_idx; + + /* Last used index value we have signalled on */ + uint16_t signalled_used; + + /* Last used index value we have signalled on */ + bool signalled_used_valid; + + bool notification; + + unsigned int inuse; + + int call_fd; + int kick_fd; + int err_fd; + unsigned int enable; + bool started; + + /* Guest addresses of our ring */ + struct vhost_vring_addr vra; +} VuVirtq; + +typedef struct VuDevRegion { + uint64_t gpa; + uint64_t size; + uint64_t qva; + uint64_t mmap_offset; + uint64_t mmap_addr; +} VuDevRegion; + +#define VHOST_USER_MAX_QUEUES 2 + +/* + * Set a reasonable maximum number of ram slots, which will be supported by + * any architecture. + */ +#define VHOST_USER_MAX_RAM_SLOTS 32 + +typedef struct VuDev { + uint32_t nregions; + VuDevRegion regions[VHOST_USER_MAX_RAM_SLOTS]; + VuVirtq vq[VHOST_USER_MAX_QUEUES]; + uint64_t features; + uint64_t protocol_features; + bool broken; + int hdrlen; +} VuDev; + +typedef struct VuVirtqElement { + unsigned int index; + unsigned int out_num; + unsigned int in_num; + struct iovec *in_sg; + struct iovec *out_sg; +} VuVirtqElement; + +static inline bool has_feature(uint64_t features, unsigned int fbit) +{ + return !!(features & (1ULL << fbit)); +} + +static inline bool vu_has_feature(VuDev *vdev, unsigned int fbit) +{ + return has_feature(vdev->features, fbit); +} + +static inline bool vu_has_protocol_feature(VuDev *vdev, unsigned int fbit) +{ + return has_feature(vdev->protocol_features, fbit); +} + +bool vu_queue_empty(VuDev *dev, VuVirtq *vq); +void vu_queue_notify(VuDev *dev, VuVirtq *vq); +void *vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz, unsigned char *buffer); +void vu_queue_detach_element(VuDev *dev, VuVirtq *vq, unsigned int index, size_t len); +void vu_queue_unpop(VuDev *dev, VuVirtq *vq, unsigned int index, size_t len); +bool vu_queue_rewind(VuDev *dev, VuVirtq *vq, unsigned int num); + +void vu_queue_fill_by_index(VuDev *dev, VuVirtq *vq, unsigned int index, + unsigned int len, unsigned int idx); +void vu_queue_fill(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem, unsigned int len, + unsigned int idx); +void vu_queue_flush(VuDev *dev, VuVirtq *vq, unsigned int count); +void vu_queue_push(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem, unsigned int len); +#endif /* VIRTIO_H */ |