|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 5/7] plat/drivers: Reintroduce the virtio ring
This patch introduces the API to create destroy the virtio ring. The
configuration API for find the number of queues and setting up
individual queues for a device.
Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
---
plat/drivers/include/virtio/virtio_bus.h | 72 ++++++++++++
plat/drivers/include/virtio/virtqueue.h | 145 +++++++++++++++++++++++
plat/drivers/virtio/virtio_bus.c | 2 +
plat/drivers/virtio/virtio_pci.c | 83 ++++++++++++-
plat/drivers/virtio/virtio_ring.c | 196 +++++++++++++++++++++++++++++++
plat/kvm/Config.uk | 1 +
plat/kvm/Makefile.uk | 2 +
7 files changed, 498 insertions(+), 3 deletions(-)
create mode 100644 plat/drivers/include/virtio/virtqueue.h
create mode 100644 plat/drivers/virtio/virtio_ring.c
diff --git a/plat/drivers/include/virtio/virtio_bus.h
b/plat/drivers/include/virtio/virtio_bus.h
index 8dffe56..f846840 100644
--- a/plat/drivers/include/virtio/virtio_bus.h
+++ b/plat/drivers/include/virtio/virtio_bus.h
@@ -42,6 +42,7 @@
#include <uk/arch/lcpu.h>
#include <uk/alloc.h>
#include <virtio/virtio_config.h>
+#include <virtio/virtqueue.h>
#ifdef __cplusplus
extern "C" {
@@ -94,6 +95,13 @@ struct virtio_config_ops {
/** Get and Set Status */
__u8 (*status_get)(struct virtio_dev *vdev);
void (*status_set)(struct virtio_dev *vdev, __u8 status);
+ /** Find the virtqueue */
+ int (*vqs_find)(struct virtio_dev *vdev, __u16 num_vq, __u16 *vq_size);
+ /** Setup the virtqueue */
+ struct virtqueue *(*vq_setup)(struct virtio_dev *vdev, __u16 num_desc,
+ __u16 queue_id,
+ virtqueue_callback_t callback,
+ struct uk_alloc *a);
};
/**
@@ -116,6 +124,8 @@ struct virtio_driver {
struct virtio_dev {
/* Feature bit describing the virtio device */
__u64 features;
+ /* List of the virtqueue for the device */
+ UK_TAILQ_HEAD(virtqueue_head, struct virtqueue) vqs;
/* Private data of the driver */
void *priv;
/* Virtio device identifier */
@@ -220,6 +230,68 @@ static inline int virtio_config_get(struct virtio_dev
*vdev, __u16 offset,
return rc;
}
+/**
+ * The helper function to find the number of the vqs supported on the device.
+ * @param vdev
+ * A reference to the virtio device.
+ * @param total_vqs
+ * The total number of virtqueues requested.
+ * @param vq_size
+ * An array of max descriptors on each virtqueue found on the
+ * virtio device
+ * @return int
+ * On success, the function return the number of available virtqueues
+ * On error,
+ * -ENOTSUP if the function is not supported.
+ */
+static inline int virtio_find_vqs(struct virtio_dev *vdev, __u16 total_vqs,
+ __u16 *vq_size)
+{
+ int rc = -ENOTSUP;
+
+ UK_ASSERT(vdev);
+
+ if (likely(vdev->cops->vqs_find))
+ rc = vdev->cops->vqs_find(vdev, total_vqs, vq_size);
+
+ return rc;
+}
+
+/**
+ * A helper function to setup an individual virtqueue.
+ * @param vdev
+ * Reference to the virtio device.
+ * @param vq_id
+ * The virtqueue queue id.
+ * @param nr_desc
+ * The count of the descriptor to be configured.
+ * @param callback
+ * A reference to callback function to invoked by the virtio device on an
+ * interrupt from the virtqueue.
+ * @param a
+ * A reference to the allocator.
+ *
+ * @return struct virtqueue *
+ * On success, a reference to the virtqueue.
+ * On error,
+ * -ENOTSUP operation not supported on the device.
+ * -ENOMEM Failed allocating the virtqueue.
+ */
+static inline struct virtqueue *virtio_vqueue_setup(struct virtio_dev *vdev,
+ __u16 vq_id, __u16 nr_desc,
+ virtqueue_callback_t callback,
+ struct uk_alloc *a)
+{
+ struct virtqueue *vq = ERR2PTR(-ENOTSUP);
+
+ UK_ASSERT(vdev && a);
+
+ if (likely(vdev->cops->vq_setup))
+ vq = vdev->cops->vq_setup(vdev, vq_id, nr_desc, callback, a);
+
+ return vq;
+}
+
static inline int virtio_has_features(__u64 features, __u8 bpos)
{
__u64 tmp_feature = 0;
diff --git a/plat/drivers/include/virtio/virtqueue.h
b/plat/drivers/include/virtio/virtqueue.h
new file mode 100644
index 0000000..a8a4bc0
--- /dev/null
+++ b/plat/drivers/include/virtio/virtqueue.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+#ifndef __PLAT_DRV_VIRTQUEUE_H__
+#define __PLAT_DRV_VIRTQUEUE_H__
+
+#include <uk/config.h>
+#include <uk/list.h>
+#include <uk/sglist.h>
+#include <uk/arch/types.h>
+#include <virtio/virtio_ring.h>
+#include <virtio/virtio_config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Type declarations
+ */
+struct virtqueue;
+struct virtio_dev;
+typedef int (*virtqueue_callback_t)(struct virtqueue *, void *priv);
+typedef int (*virtqueue_notify_host_t)(struct virtio_dev *, __u16 queue_nr);
+
+/**
+ * Structure to describe the virtqueue.
+ */
+struct virtqueue {
+ /* Reference the virtio_dev it belong to */
+ struct virtio_dev *vdev;
+ /* Virtqueue identifier */
+ __u16 queue_id;
+ /* Notify to the host */
+ virtqueue_notify_host_t vq_notify_host;
+ /* Callback from the virtqueue */
+ virtqueue_callback_t vq_callback;
+ /* Next entry of the queue */
+ UK_TAILQ_ENTRY(struct virtqueue) next;
+ /* Private data structure used by the driver of the queue */
+ void *priv;
+};
+
+/**
+ * Fetch the physical address of the descriptor ring.
+ * @param vq
+ * Reference to the virtqueue.
+ *
+ * @return
+ * Return the guest physical address of the vring.
+ */
+__phys_addr virtqueue_physaddr(struct virtqueue *vq);
+
+/**
+ * Negotiate with the virtqueue features.
+ * @param feature_set
+ * The feature set the device request.
+ *
+ * @return __u64
+ * The negotiated feature set.
+ */
+__u64 virtqueue_feature_negotiate(__u64 feature_set);
+
+/**
+ * Allocate a virtqueue.
+ * @param queue_id
+ * The virtqueue hw id.
+ * @param nr_descs
+ * The number of descriptor for the queue.
+ * @param align
+ * The memory alignment for the ring memory.
+ * @param callback
+ * A reference to callback to the virtio-dev.
+ * @param notify
+ * A reference to notification function to the host.
+ * @param vdev:
+ * A reference to the virtio device.
+ * @param a:
+ * A reference to the allocator.
+ *
+ * @return struct virtqueue *
+ * On success, return a reference to the virtqueue.
+ * On failure,
+ * -ENOMEM: Failed to allocate the queue.
+ */
+struct virtqueue *virtqueue_create(__u16 queue_id, __u16 nr_descs, __u16 align,
+ virtqueue_callback_t callback,
+ virtqueue_notify_host_t notify,
+ struct virtio_dev *vdev, struct uk_alloc *a);
+
+/**
+ * Check the virtqueue if full.
+ * @param vq
+ * A reference to the virtqueue.
+ * @return int
+ * 1 on full,
+ * 0 otherwise
+ */
+int virtqueue_is_full(struct virtqueue *vq);
+
+/*
+ * Destroy a virtual queue
+ * @param vq
+ * A reference to the virtual queue
+ * @param a
+ * Reference to the memory allocator
+ */
+void virtqueue_destroy(struct virtqueue *vq, struct uk_alloc *a);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PLAT_DRV_VIRTQUEUE_H__ */
diff --git a/plat/drivers/virtio/virtio_bus.c b/plat/drivers/virtio/virtio_bus.c
index b40a270..48a2467 100644
--- a/plat/drivers/virtio/virtio_bus.c
+++ b/plat/drivers/virtio/virtio_bus.c
@@ -151,6 +151,8 @@ int virtio_bus_register_device(struct virtio_dev *vdev)
return rc;
}
+ /* Initialize the virtqueue list */
+ UK_TAILQ_INIT(&vdev->vqs);
/* Calling the driver add device */
rc = drv->add_dev(vdev);
diff --git a/plat/drivers/virtio/virtio_pci.c b/plat/drivers/virtio/virtio_pci.c
index 1c1d11c..4e29e62 100644
--- a/plat/drivers/virtio/virtio_pci.c
+++ b/plat/drivers/virtio/virtio_pci.c
@@ -42,6 +42,7 @@
#include <pci/pci_bus.h>
#include <virtio/virtio_config.h>
#include <virtio/virtio_bus.h>
+#include <virtio/virtqueue.h>
#include <virtio/virtio_pci.h>
#define VENDOR_QUMRANET_VIRTIO (0x1AF4)
@@ -65,12 +66,13 @@ struct virtio_pci_dev {
};
/**
- * Fetch the virtio pci information from the virtiodev.
+ * Fetch the virtio pci information from the virtio device.
+ * @param vdev
+ * Reference to the virtio device.
*/
#define to_virtiopcidev(vdev) \
__containerof(vdev, struct virtio_pci_dev, vdev)
-
/**
* Static function declaration.
*/
@@ -82,8 +84,15 @@ static int vpci_legacy_pci_config_get(struct virtio_dev
*vdev, __u16 offset,
static __u64 vpci_legacy_pci_features_get(struct virtio_dev *vdev);
static void vpci_legacy_pci_features_set(struct virtio_dev *vdev,
__u64 features);
+static int vpci_legacy_pci_vq_find(struct virtio_dev *vdev, __u16 num_vq,
+ __u16 *qdesc_size);
static void vpci_legacy_pci_status_set(struct virtio_dev *vdev, __u8 status);
static __u8 vpci_legacy_pci_status_get(struct virtio_dev *vdev);
+static struct virtqueue *vpci_legacy_vq_setup(struct virtio_dev *vdev,
+ __u16 queue_id,
+ __u16 num_desc,
+ virtqueue_callback_t callback,
+ struct uk_alloc *a);
static inline void virtio_device_id_add(struct virtio_dev *vdev,
__u16 pci_dev_id,
__u16 vpci_dev_id_start);
@@ -101,8 +110,73 @@ static struct virtio_config_ops vpci_legacy_ops = {
.features_set = vpci_legacy_pci_features_set,
.status_get = vpci_legacy_pci_status_get,
.status_set = vpci_legacy_pci_status_set,
+ .vqs_find = vpci_legacy_pci_vq_find,
+ .vq_setup = vpci_legacy_vq_setup,
};
+static struct virtqueue *vpci_legacy_vq_setup(struct virtio_dev *vdev,
+ __u16 queue_id,
+ __u16 num_desc,
+ virtqueue_callback_t callback,
+ struct uk_alloc *a)
+{
+ struct virtio_pci_dev *vpdev = NULL;
+ struct virtqueue *vq;
+ __phys_addr addr;
+ long flags;
+
+ UK_ASSERT(vdev != NULL);
+
+ vpdev = to_virtiopcidev(vdev);
+ vq = virtqueue_create(queue_id, num_desc, VIRTIO_PCI_VRING_ALIGN,
+ callback, NULL, vdev, a);
+ if (PTRISERR(vq)) {
+ uk_pr_err("Failed to create the virtqueue: %d\n",
+ PTR2ERR(vq));
+ goto err_exit;
+ }
+
+ /* Physical address of the queue */
+ addr = virtqueue_physaddr(vq);
+ /* Select the queue of interest */
+ virtio_cwrite16((void *)(unsigned long)vpdev->pci_base_addr,
+ VIRTIO_PCI_QUEUE_SEL, queue_id);
+ virtio_cwrite32((void *)(unsigned long)vpdev->pci_base_addr,
+ VIRTIO_PCI_QUEUE_PFN,
+ addr >> VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+
+ flags = ukplat_lcpu_save_irqf();
+ UK_TAILQ_INSERT_TAIL(&vpdev->vdev.vqs, vq, next);
+ ukplat_lcpu_restore_irqf(flags);
+
+err_exit:
+ return vq;
+}
+
+static int vpci_legacy_pci_vq_find(struct virtio_dev *vdev, __u16 num_vqs,
+ __u16 *qdesc_size)
+{
+ struct virtio_pci_dev *vpdev = NULL;
+ int vq_cnt = 0, i = 0;
+
+ UK_ASSERT(vdev);
+ vpdev = to_virtiopcidev(vdev);
+
+ for (i = 0; i < num_vqs; i++) {
+ virtio_cwrite16((void *) (unsigned long)vpdev->pci_base_addr,
+ VIRTIO_PCI_QUEUE_SEL, i);
+ qdesc_size[i] = virtio_cread16(
+ (void *) (unsigned long)vpdev->pci_base_addr,
+ VIRTIO_PCI_QUEUE_SIZE);
+ if (unlikely(!qdesc_size[i])) {
+ uk_pr_err("Virtqueue %d not available\n", i);
+ continue;
+ }
+ vq_cnt++;
+ }
+ return vq_cnt;
+}
+
static int vpci_legacy_pci_config_set(struct virtio_dev *vdev, __u16 offset,
const void *buf, __u32 len)
{
@@ -212,6 +286,8 @@ static void vpci_legacy_pci_features_set(struct virtio_dev
*vdev,
UK_ASSERT(vdev);
vpdev = to_virtiopcidev(vdev);
+ /* Mask out features not supported by the virtqueue driver */
+ features = virtqueue_feature_negotiate(features);
virtio_cwrite32((void *) (unsigned long)vpdev->pci_base_addr,
VIRTIO_PCI_GUEST_FEATURES, (__u32)features);
}
@@ -243,7 +319,7 @@ static int virtio_pci_legacy_add_dev(struct pci_device
*pci_dev,
/* Mapping the virtio device identifier */
virtio_device_id_add(&vpci_dev->vdev, pci_dev->id.device_id,
- VIRTIO_PCI_LEGACY_DEVICEID_START);
+ VIRTIO_PCI_LEGACY_DEVICEID_START);
return 0;
}
@@ -284,6 +360,7 @@ static int virtio_pci_add_dev(struct pci_device *pci_dev)
exit:
return rc;
+
free_pci_dev:
uk_free(a, vpci_dev);
goto exit;
diff --git a/plat/drivers/virtio/virtio_ring.c
b/plat/drivers/virtio/virtio_ring.c
new file mode 100644
index 0000000..ba91594
--- /dev/null
+++ b/plat/drivers/virtio/virtio_ring.c
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+/**
+ * Inspired from the FreeBSD.
+ * Commit-id: a89e7a10d501
+ */
+#include <uk/config.h>
+#include <string.h>
+#include <uk/print.h>
+#include <uk/errptr.h>
+#include <cpu.h>
+#include <uk/sglist.h>
+#include <uk/arch/atomic.h>
+#include <uk/plat/io.h>
+#include <virtio/virtio_ring.h>
+#include <virtio/virtqueue.h>
+
+#define VIRTQUEUE_MAX_SIZE 32768
+#define to_virtqueue_vring(vq) \
+ __containerof(vq, struct virtqueue_vring, vq)
+
+struct virtqueue_desc_info {
+ void *cookie;
+ __u16 desc_count;
+};
+
+struct virtqueue_vring {
+ struct virtqueue vq;
+ /* Descriptor Ring */
+ struct vring vring;
+ /* Reference to the vring */
+ void *vring_mem;
+ /* Keep track of available descriptors */
+ __u16 desc_avail;
+ /* Index of the next available slot */
+ __u16 head_free_desc;
+ /* Index of the last used descriptor by the host */
+ __u16 last_used_desc_idx;
+ /* Cookie to identify driver buffer */
+ struct virtqueue_desc_info vq_info[];
+};
+
+/**
+ * Static function Declaration(s).
+ */
+static void virtqueue_vring_init(struct virtqueue_vring *vrq, __u16 nr_desc,
+ __u16 align);
+
+/**
+ * Driver implementation
+ */
+__u64 virtqueue_feature_negotiate(__u64 feature_set)
+{
+ __u64 feature = (1ULL << VIRTIO_TRANSPORT_F_START) - 1;
+
+ /**
+ * Currently out vring driver does not support any ring feature. We will
+ * add support to transport feature in the future.
+ */
+ feature &= feature_set;
+ return feature;
+}
+
+__phys_addr virtqueue_physaddr(struct virtqueue *vq)
+{
+ struct virtqueue_vring *vrq = NULL;
+
+ UK_ASSERT(vq);
+
+ vrq = to_virtqueue_vring(vq);
+ return ukplat_virt_to_phys(vrq->vring_mem);
+}
+
+static void virtqueue_vring_init(struct virtqueue_vring *vrq, __u16 nr_desc,
+ __u16 align)
+{
+ int i = 0;
+
+ vring_init(&vrq->vring, nr_desc, vrq->vring_mem, align);
+
+ vrq->desc_avail = vrq->vring.num;
+ vrq->head_free_desc = 0;
+ vrq->last_used_desc_idx = 0;
+ for (i = 0; i < nr_desc - 1; i++)
+ vrq->vring.desc[i].next = i + 1;
+ /**
+ * When we reach this descriptor we have completely used all the
+ * descriptor in the vring.
+ */
+ vrq->vring.desc[nr_desc - 1].next = VIRTQUEUE_MAX_SIZE;
+}
+
+struct virtqueue *virtqueue_create(__u16 queue_id, __u16 nr_descs, __u16 align,
+ virtqueue_callback_t callback,
+ virtqueue_notify_host_t notify,
+ struct virtio_dev *vdev, struct uk_alloc *a)
+{
+ struct virtqueue_vring *vrq;
+ struct virtqueue *vq;
+ int rc;
+ size_t ring_size = 0;
+
+ UK_ASSERT(a);
+
+ vrq = uk_malloc(a, sizeof(struct virtqueue) +
+ nr_descs * sizeof(struct virtqueue_desc_info));
+ if (!vrq) {
+ uk_pr_err("Allocation of virtqueue failed\n");
+ rc = -ENOMEM;
+ goto err_exit;
+ }
+ /**
+ * Initialize the value before referencing it in
+ * uk_posix_memalign as we don't set NULL on all failures in the
+ * allocation.
+ */
+ vrq->vring_mem = NULL;
+
+ ring_size = vring_size(nr_descs, align);
+ uk_posix_memalign(a, (void **)&vrq->vring_mem, __PAGE_SIZE, ring_size);
+ if (!vrq->vring_mem) {
+ uk_pr_err("Allocation of vring failed\n");
+ rc = -ENOMEM;
+ goto err_freevq;
+ }
+ memset(vrq->vring_mem, 0, ring_size);
+ virtqueue_vring_init(vrq, nr_descs, align);
+
+ vq = &vrq->vq;
+ vq->queue_id = queue_id;
+ vq->vdev = vdev;
+ vq->vq_callback = callback;
+ vq->vq_notify_host = notify;
+ return vq;
+
+err_freevq:
+ uk_free(a, vrq);
+err_exit:
+ return ERR2PTR(rc);
+}
+
+void virtqueue_destroy(struct virtqueue *vq, struct uk_alloc *a)
+{
+ struct virtqueue_vring *vrq;
+
+ UK_ASSERT(vq);
+
+ vrq = to_virtqueue_vring(vq);
+
+ /* Free the ring */
+ uk_free(a, vrq->vring_mem);
+
+ /* Free the virtqueue metadata */
+ uk_free(a, vrq);
+}
+
+int virtqueue_is_full(struct virtqueue *vq)
+{
+ struct virtqueue_vring *vrq;
+
+ UK_ASSERT(vq);
+
+ vrq = to_virtqueue_vring(vq);
+ return (vrq->desc_avail == 0);
+}
diff --git a/plat/kvm/Config.uk b/plat/kvm/Config.uk
index afcedc0..13e5575 100644
--- a/plat/kvm/Config.uk
+++ b/plat/kvm/Config.uk
@@ -57,6 +57,7 @@ config VIRTIO_BUS
depends on (ARCH_X86_64)
depends on LIBUKBUS
select LIBUKALLOC
+ select LIBUKSGLIST
help
Virtio bus driver for probing and operating virtio device and
transport layer.
diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk
index 986bf4a..ccc8319 100644
--- a/plat/kvm/Makefile.uk
+++ b/plat/kvm/Makefile.uk
@@ -92,5 +92,7 @@ LIBKVMVIRTIO_ASINCLUDES-y +=
-I$(UK_PLAT_DRIVERS_BASE)/include
LIBKVMVIRTIO_CINCLUDES-y += -I$(UK_PLAT_DRIVERS_BASE)/include
LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_BUS) +=\
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_bus.c
+LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_BUS) +=\
+
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_ring.c
LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_PCI) +=\
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_pci.c
--
2.7.4
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |