aboutsummaryrefslogtreecommitdiffstats
path: root/virtio_loopback.h
diff options
context:
space:
mode:
Diffstat (limited to 'virtio_loopback.h')
-rw-r--r--virtio_loopback.h140
1 files changed, 78 insertions, 62 deletions
diff --git a/virtio_loopback.h b/virtio_loopback.h
index 5400cd7..49ae219 100644
--- a/virtio_loopback.h
+++ b/virtio_loopback.h
@@ -1,20 +1,20 @@
/*
* Based on:
- * 1) virtio.h of Qemu project
+ * 1) virtio.h of QEMU project
*
* Copyright IBM, Corp. 2007
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
- * 2) virtio-mmio.h of Qemu project
+ * 2) virtio-mmio.h of QEMU project
*
* Copyright (c) 2011 Linaro Limited
*
* Author:
* Peter Maydell <peter.maydell@linaro.org>
*
- * 3) vhost.h of Qemu project
+ * 3) vhost.h of QEMU project
*
* Copyright 2022 Virtual Open Systems SAS.
*
@@ -43,15 +43,19 @@
/* Virtio vendor ID - Read Only */
#define VIRTIO_MMIO_VENDOR_ID 0x00c
-/* Bitmask of the features supported by the device (host)
- * (32 bits per set) - Read Only */
+/*
+ * Bitmask of the features supported by the device (host)
+ * (32 bits per set) - Read Only
+ */
#define VIRTIO_MMIO_DEVICE_FEATURES 0x010
/* Device (host) features set selector - Write Only */
#define VIRTIO_MMIO_DEVICE_FEATURES_SEL 0x014
-/* Bitmask of features activated by the driver (guest)
- * (32 bits per set) - Write Only */
+/*
+ * Bitmask of features activated by the driver (guest)
+ * (32 bits per set) - Write Only
+ */
#define VIRTIO_MMIO_DRIVER_FEATURES 0x020
/* Activated features set selector - Write Only */
@@ -117,8 +121,10 @@
/* Configuration atomicity value */
#define VIRTIO_MMIO_CONFIG_GENERATION 0x0fc
-/* The config space is defined by each driver as
- * the per-driver configuration space - Read Write */
+/*
+ * The config space is defined by each driver as
+ * the per-driver configuration space - Read Write
+ */
#define VIRTIO_MMIO_CONFIG 0x100
/*
@@ -134,7 +140,7 @@
/* Virtio loopback driver related */
-/* Qemu defines */
+/* QEMU defines */
#define VIRT_MAGIC 0x74726976 /* 'virt' */
#define VIRT_VERSION 2
#define VIRT_VERSION_LEGACY 1
@@ -150,7 +156,8 @@
#define PAGE_SIZE 4096
#define EFD_INIT _IOC(_IOC_WRITE, 'k', 1, sizeof(efd_data_t))
#define WAKEUP _IOC(_IOC_WRITE, 'k', 2, 0)
-#define START_LOOPBACK _IOC(_IOC_WRITE, 'k', 3, sizeof(virtio_device_info_struct_t))
+#define START_LOOPBACK _IOC(_IOC_WRITE, 'k', 3, \
+ sizeof(virtio_device_info_struct_t))
#define IRQ _IOC(_IOC_WRITE, 'k', 4, sizeof(int))
#define SHARE_VQS _IOC(_IOC_WRITE, 'k', 5, 0)
#define SHARE_BUF _IOC(_IOC_WRITE, 'k', 6, sizeof(uint64_t))
@@ -189,13 +196,17 @@ typedef struct VirtIOMMIOProxy {
#define VRING_PACKED_DESC_F_AVAIL 7
#define VRING_PACKED_DESC_F_USED 15
-/* The Host uses this in used->flags to advise the Guest: don't kick me when
+/*
+ * The Host uses this in used->flags to advise the Guest: don't kick me when
* you add a buffer. It's unreliable, so it's simply an optimization. Guest
- * will still kick if it's out of buffers. */
+ * will still kick if it's out of buffers.
+ */
#define VRING_USED_F_NO_NOTIFY 1
-/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
+/*
+ * The Guest uses this in avail->flags to advise the Host: don't interrupt me
* when you consume a buffer. It's unreliable, so it's simply an
- * optimization. */
+ * optimization.
+ */
#define VRING_AVAIL_F_NO_INTERRUPT 1
/* Enable events in packed ring. */
@@ -218,13 +229,18 @@ typedef struct VirtIOMMIOProxy {
/* We support indirect buffer descriptors */
#define VIRTIO_RING_F_INDIRECT_DESC 28
-/* The Guest publishes the used index for which it expects an interrupt
- * at the end of the avail ring. Host should ignore the avail->flags field. */
-/* The Host publishes the avail index for which it expects a kick
- * at the end of the used ring. Guest should ignore the used->flags field. */
+/*
+ * The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field.
+ */
+/*
+ * The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field.
+ */
#define VIRTIO_RING_F_EVENT_IDX 29
-/* Alignment requirements for vring elements.
+/*
+ * Alignment requirements for vring elements.
* When using pre-virtio 1.0 layout, these fall out naturally.
*/
#define VRING_AVAIL_ALIGN_SIZE 2
@@ -232,8 +248,7 @@ typedef struct VirtIOMMIOProxy {
#define VRING_DESC_ALIGN_SIZE 16
/******************/
-typedef struct VRing
-{
+typedef struct VRing {
unsigned int num;
unsigned int num_default;
unsigned int align;
@@ -242,8 +257,7 @@ typedef struct VRing
uint64_t used;
} VRing;
-typedef struct VRingDesc
-{
+typedef struct VRingDesc {
uint64_t addr;
uint32_t len;
uint16_t flags;
@@ -257,28 +271,24 @@ typedef struct VRingPackedDesc {
uint16_t flags;
} VRingPackedDesc;
-typedef struct VRingAvail
-{
+typedef struct VRingAvail {
uint16_t flags;
uint16_t idx;
uint16_t ring[];
} VRingAvail;
-typedef struct VRingUsedElem
-{
+typedef struct VRingUsedElem {
uint32_t id;
uint32_t len;
} VRingUsedElem;
-typedef struct VRingUsed
-{
+typedef struct VRingUsed {
uint16_t flags;
uint16_t idx;
VRingUsedElem ring[];
} VRingUsed;
-typedef struct VirtQueueElement
-{
+typedef struct VirtQueueElement {
unsigned int index;
unsigned int len;
unsigned int ndescs;
@@ -294,8 +304,7 @@ typedef struct VirtIODevice VirtIODevice;
typedef struct VirtQueue VirtQueue;
typedef void (*VirtIOHandleOutput)(VirtIODevice *, VirtQueue *);
-typedef struct VirtQueue
-{
+typedef struct VirtQueue {
VRing vring;
VirtQueueElement *used_elems;
@@ -330,7 +339,6 @@ typedef struct VirtQueue
EventNotifier guest_notifier;
EventNotifier host_notifier;
bool host_notifier_enabled;
- //QLIST_ENTRY(VirtQueue) node;
} VirtQueue;
typedef struct VirtIORNG VirtIORNG;
@@ -338,9 +346,7 @@ typedef struct VHostUserRNG VHostUserRNG;
typedef struct VirtioDeviceClass VirtioDeviceClass;
typedef struct VirtioBus VirtioBus;
-typedef struct VirtIODevice
-{
- //DeviceState parent_obj;
+typedef struct VirtIODevice {
VirtioBus *vbus;
VirtioDeviceClass *vdev_class;
const char *name;
@@ -356,7 +362,6 @@ typedef struct VirtIODevice
uint32_t generation;
int nvectors;
VirtQueue *vq;
- //MemoryListener listener;
uint16_t device_id;
bool vm_running;
bool broken; /* device in invalid state, needs reset */
@@ -366,14 +371,11 @@ typedef struct VirtIODevice
bool started;
bool start_on_kick; /* when virtio 1.0 feature has not been negotiated */
bool disable_legacy_check;
- //VMChangeStateEntry *vmstate;
char *bus_name;
uint8_t device_endian;
bool use_guest_notifier_mask;
VirtIORNG *vrng;
VHostUserRNG *vhrng;
- //AddressSpace *dma_as;
- //QLIST_HEAD(, VirtQueue) *vector_queues;
} VirtIODevice;
typedef struct efd_data {
@@ -389,14 +391,17 @@ typedef struct virtio_device_info_struct {
} virtio_device_info_struct_t;
-/* proto */
+
+/* Negotiation structs */
+
+typedef struct { int counter; } atomic_t;
+
typedef struct virtio_neg {
uint64_t notification;
uint64_t data;
uint64_t size;
bool read;
- bool done;
- bool request_op;
+ atomic_t done;
} virtio_neg_t;
@@ -498,18 +503,21 @@ typedef struct VirtioDeviceClass {
void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
void (*reset)(VirtIODevice *vdev);
void (*set_status)(VirtIODevice *vdev, uint8_t val);
- /* For transitional devices, this is a bitmap of features
+ /*
+ * For transitional devices, this is a bitmap of features
* that are only exposed on the legacy interface but not
* the modern one.
*/
uint64_t legacy_features;
- /* Test and clear event pending status.
+ /*
+ * Test and clear event pending status.
* Should be called after unmask to avoid losing events.
* If backend does not support masking,
* must check in frontend instead.
*/
bool (*guest_notifier_pending)(VirtIODevice *vdev, int n);
- /* Mask/unmask events from this vq. Any events reported
+ /*
+ * Mask/unmask events from this vq. Any events reported
* while masked will become pending.
* If backend does not support masking,
* must mask in frontend instead.
@@ -517,13 +525,15 @@ typedef struct VirtioDeviceClass {
void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask);
int (*start_ioeventfd)(VirtIODevice *vdev);
void (*stop_ioeventfd)(VirtIODevice *vdev);
- /* Saving and loading of a device; trying to deprecate save/load
+ /*
+ * Saving and loading of a device; trying to deprecate save/load
* use vmsd for new devices.
*/
- /* Post load hook in vmsd is called early while device is processed, and
- * when VirtIODevice isn't fully initialized. Devices should use this instead,
- * unless they specifically want to verify the migration stream as it's
- * processed, e.g. for bounds checking.
+ /*
+ * Post load hook in vmsd is called early while device is processed, and
+ * when VirtIODevice isn't fully initialized. Devices should use this
+ * instead, unless they specifically want to verify the migration stream
+ * as it's processed, e.g. for bounds checking.
*/
int (*post_load)(VirtIODevice *vdev);
bool (*primary_unplug_pending)(void *opaque);
@@ -537,10 +547,10 @@ void handle_input(VirtIODevice *vdev, VirtQueue *vq);
void *my_select(void *data);
void *wait_read_write(void *data);
void *my_notify(void *data);
-void create_rng_struct (void);
+void create_rng_struct(void);
void print_neg_flag(uint64_t neg_flag, bool read);
-void adapter_read_write_cb (void);
-int virtio_mmio_start(void);
+void adapter_read_write_cb(void);
+int virtio_loopback_start(void);
int virtio_queue_ready(VirtQueue *vq);
void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
@@ -551,7 +561,8 @@ bool virtio_has_feature(uint64_t features, unsigned int fbit);
int virtio_queue_empty(VirtQueue *vq);
void *virtqueue_pop(VirtQueue *vq, size_t sz);
-void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, unsigned int len);
+void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
+ unsigned int len);
size_t iov_from_buf(const struct iovec *iov, unsigned int iov_cnt,
size_t offset, const void *buf, size_t bytes);
bool virtqueue_get_head(VirtQueue *vq, unsigned int idx,
@@ -571,7 +582,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
void virtio_dev_init(VirtIODevice *vdev, const char *name,
uint16_t device_id, size_t config_size);
-void virtio_mmio_bus_init(VirtioBus *k);
+void virtio_loopback_bus_init(VirtioBus *k);
int virtio_bus_set_host_notifier(VirtioBus *vbus, int n, bool assign);
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
@@ -594,17 +605,22 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
int virtqueue_split_read_next_desc(VirtIODevice *vdev, VRingDesc *desc,
unsigned int max, unsigned int *next);
-/* Do we get callbacks when the ring is completely used, even if we've
- * suppressed them? */
+/*
+ * Do we get callbacks when the ring is completely used, even if we've
+ * suppressed them?
+ */
#define VIRTIO_F_NOTIFY_ON_EMPTY 24
#define VIRTIO_CONFIG_S_FEATURES_OK 8
#define VIRTIO_CONFIG_S_DRIVER_OK 4
#define VIRTIO_F_VERSION_1 32
#define VIRTIO_F_ACCESS_PLATFORM 33
-/* Legacy name for VIRTIO_F_ACCESS_PLATFORM (for compatibility with old userspace) */
+/*
+ * Legacy name for VIRTIO_F_ACCESS_PLATFORM
+ * (for compatibility with old userspace)
+ */
#define VIRTIO_F_IOMMU_PLATFORM VIRTIO_F_ACCESS_PLATFORM
-/* Qemu Aligned functions */
+/* QEMU Aligned functions */
/*
* Round number down to multiple. Safe when m is not a power of 2 (see
* ROUND_DOWN for a faster version when a power of 2 is guaranteed).