aboutgitcodebugslistschat
path: root/virtio.h
diff options
context:
space:
mode:
Diffstat (limited to 'virtio.h')
-rw-r--r--virtio.h171
1 files changed, 117 insertions, 54 deletions
diff --git a/virtio.h b/virtio.h
index e334355..6410d60 100644
--- a/virtio.h
+++ b/virtio.h
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-//
-/* come parts copied from QEMU subprojects/libvhost-user/libvhost-user.h */
+/*
+ * virtio API, vring and virtqueue functions definition
+ *
+ * Copyright Red Hat
+ * Author: Laurent Vivier <lvivier@redhat.com>
+ */
#ifndef VIRTIO_H
#define VIRTIO_H
@@ -8,61 +12,81 @@
#include <stdbool.h>
#include <linux/vhost_types.h>
+/* Maximum size of a virtqueue */
#define VIRTQUEUE_MAX_SIZE 1024
-#define vu_panic(vdev, ...) \
- do { \
- (vdev)->broken = true; \
- err( __VA_ARGS__ ); \
- } while (0)
-
-typedef struct VuRing {
+/**
+ * struct vu_ring - Virtqueue rings
+ * @num: Size of the queue
+ * @desc: Descriptor ring
+ * @avail: Available ring
+ * @used: Used ring
+ * @log_guest_addr: Guest address for logging
+ * @flags: Vring flags
+ * VHOST_VRING_F_LOG is set if log address is valid
+ */
+struct vu_ring {
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 */
+};
+
+/**
+ * struct vu_virtq - Virtqueue definition
+ * @vring: Virtqueue rings
+ * @last_avail_idx: Next head to pop
+ * @shadow_avail_idx: Last avail_idx read from VQ.
+ * @used_idx: Descriptor ring current index
+ * @signalled_used: Last used index value we have signalled on
+ * @signalled_used_valid: True if signalled_used if valid
+ * @notification: True if the queues notify (via event
+ * index or interrupt)
+ * @inuse: Number of entries in use
+ * @call_fd: The event file descriptor to signal when
+ * buffers are used.
+ * @kick_fd: The event file descriptor for adding
+ * buffers to the vring
+ * @err_fd: The event file descriptor to signal when
+ * error occurs
+ * @enable: True if the virtqueue is enabled
+ * @started: True if the virtqueue is started
+ * @vra: QEMU address of our rings
+ */
+struct vu_virtq {
+ struct vu_ring vring;
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 {
+};
+
+/**
+ * struct vu_dev_region - guest shared memory region
+ * @gpa: Guest physical address of the region
+ * @size: Memory size in bytes
+ * @qva: QEMU virtual address
+ * @mmap_offset: Offset where the region starts in the mapped memory
+ * @mmap_addr: Address of the mapped memory
+ */
+struct vu_dev_region {
uint64_t gpa;
uint64_t size;
uint64_t qva;
uint64_t mmap_offset;
uint64_t mmap_addr;
-} VuDevRegion;
+};
#define VHOST_USER_MAX_QUEUES 2
@@ -72,50 +96,89 @@ typedef struct VuDevRegion {
*/
#define VHOST_USER_MAX_RAM_SLOTS 32
-typedef struct VuDev {
+/**
+ * struct vu_dev - vhost-user device information
+ * @context: Execution context
+ * @nregions: Number of shared memory regions
+ * @regions: Guest shared memory regions
+ * @features: Vhost-user features
+ * @protocol_features: Vhost-user protocol features
+ */
+struct vu_dev {
+ struct ctx *context;
uint32_t nregions;
- VuDevRegion regions[VHOST_USER_MAX_RAM_SLOTS];
- VuVirtq vq[VHOST_USER_MAX_QUEUES];
+ struct vu_dev_region regions[VHOST_USER_MAX_RAM_SLOTS];
+ struct vu_virtq vq[VHOST_USER_MAX_QUEUES];
uint64_t features;
uint64_t protocol_features;
- bool broken;
- int hdrlen;
-} VuDev;
-
-typedef struct VuVirtqElement {
+};
+
+/**
+ * struct vu_virtq_element - virtqueue element
+ * @index: Descriptor ring index
+ * @out_num: Number of outgoing iovec buffers
+ * @in_num: Number of incoming iovec buffers
+ * @in_sg: Incoming iovec buffers
+ * @out_sg: Outgoing iovec buffers
+ */
+struct vu_virtq_element {
unsigned int index;
unsigned int out_num;
unsigned int in_num;
struct iovec *in_sg;
struct iovec *out_sg;
-} VuVirtqElement;
-
+};
+
+/**
+ * has_feature() - Check a feature bit in a features set
+ * @features: Features set
+ * @fb: Feature bit to check
+ *
+ * Return: True if the feature bit is set
+ */
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)
+/**
+ * vu_has_feature() - Check if a virtio-net feature is available
+ * @vdev: Vhost-user device
+ * @bit: Feature to check
+ *
+ * Return: True if the feature is available
+ */
+static inline bool vu_has_feature(const struct vu_dev *vdev,
+ unsigned int fbit)
{
return has_feature(vdev->features, fbit);
}
-static inline bool vu_has_protocol_feature(VuDev *vdev, unsigned int fbit)
+/**
+ * vu_has_protocol_feature() - Check if a vhost-user feature is available
+ * @vdev: Vhost-user device
+ * @bit: Feature to check
+ *
+ * Return: True if the feature is available
+ */
+/* cppcheck-suppress unusedFunction */
+static inline bool vu_has_protocol_feature(const struct vu_dev *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,
+bool vu_queue_empty(struct vu_virtq *vq);
+void vu_queue_notify(const struct vu_dev *dev, struct vu_virtq *vq);
+int vu_queue_pop(struct vu_dev *dev, struct vu_virtq *vq,
+ struct vu_virtq_element *elem);
+void vu_queue_detach_element(struct vu_virtq *vq);
+void vu_queue_unpop(struct vu_virtq *vq);
+bool vu_queue_rewind(struct vu_virtq *vq, unsigned int num);
+void vu_queue_fill_by_index(struct vu_virtq *vq, unsigned int index,
unsigned int len, unsigned int idx);
-void vu_queue_fill(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem, unsigned int len,
+void vu_queue_fill(struct vu_virtq *vq,
+ const struct vu_virtq_element *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);
+void vu_queue_flush(struct vu_virtq *vq, unsigned int count);
#endif /* VIRTIO_H */