aboutsummaryrefslogtreecommitdiffstats
path: root/vhost_user_rng.c
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-11-10 15:47:34 +0100
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-11-29 12:43:41 +0100
commit9ad83030ef18c04beae09a6acf9800378a8378bc (patch)
tree55fb7db83e7c99cf1260d9e3fbc6dce2f545eee9 /vhost_user_rng.c
parent247ecdad23065b8e8df08c939915d7551b6e0c21 (diff)
Add virtio-loopback-adapter
The virtio-loopback-adapter is part of the Virtio Loopback architecture detailed in the following link: https://git.virtualopensystems.com/virtio-loopback/docs The following vhost-user devices are supported: - vhost-user-blk - vhost-user-rng - vhost-user-input - vhost-user-gpio - vhost-user-sound Bug-AGL: SPEC-4834 Change-Id: I4edb28faf370992f5f45390f5c4240a0f5c3084c Signed-off-by: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com>
Diffstat (limited to 'vhost_user_rng.c')
-rw-r--r--vhost_user_rng.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/vhost_user_rng.c b/vhost_user_rng.c
new file mode 100644
index 0000000..c727636
--- /dev/null
+++ b/vhost_user_rng.c
@@ -0,0 +1,201 @@
+/*
+ * Based on vhost-user-rng of QEMU project
+ *
+ * Copyright (c) 2021 Mathieu Poirier <mathieu.poirier@linaro.org>
+ *
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include <sys/param.h>
+
+/* Project header files */
+#include "vhost_loopback.h"
+#include "vhost_user_rng.h"
+
+#ifdef DEBUG
+#define DBG(...) printf("vhost-user-rng: " __VA_ARGS__)
+#else
+#define DBG(...)
+#endif /* DEBUG */
+
+static void vu_rng_start(VirtIODevice *vdev)
+{
+ VHostUserRNG *rng = vdev->vhrng;
+ VirtioBus *k = vdev->vbus;
+ int ret;
+ int i;
+
+ /* TODO: This might be deleted in future */
+ if (!k->set_guest_notifiers) {
+ DBG("binding does not support guest notifiers\n");
+ return;
+ }
+
+ ret = vhost_dev_enable_notifiers(rng->vhost_dev, vdev);
+ if (ret < 0) {
+ DBG("Error enabling host notifiers: %d\n", ret);
+ return;
+ }
+
+ ret = k->set_guest_notifiers(vdev, rng->vhost_dev->nvqs, true);
+ if (ret < 0) {
+ DBG("Error binding guest notifier: %d\n", ret);
+ return;
+ }
+
+ rng->vhost_dev->acked_features = vdev->guest_features;
+ DBG("rng->vhost_dev->acked_features: 0x%lx\n", vdev->guest_features);
+
+ ret = vhost_dev_start(rng->vhost_dev, vdev, true);
+ if (ret < 0) {
+ DBG("Error starting vhost-user-rng: %d\n", ret);
+ return;
+ }
+
+ /*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+ for (i = 0; i < rng->vhost_dev->nvqs; i++) {
+ vhost_virtqueue_mask(rng->vhost_dev, vdev, i, false);
+ }
+
+ /* Wait a bit for the vrings to be set in vhost-user-device */
+ sleep(1);
+
+}
+
+/* TODO: We need to implement this function in a future release */
+static void vu_rng_stop(VirtIODevice *vdev)
+{
+ VHostUserRNG *rng = vdev->vhrng;
+}
+
+
+static uint64_t vu_rng_get_features(VirtIODevice *vdev,
+ uint64_t requested_features)
+{
+ /* No feature bits used yet */
+ return requested_features;
+}
+
+/* TODO: We need to implement this function in a future release */
+static void vu_rng_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
+{
+ VHostUserRNG *rng = vdev->vhrng;
+
+ /* vhost_virtqueue_mask(&rng->vhost_dev, vdev, idx, mask); */
+}
+
+/* TODO: We need to implement this function in a future release */
+static bool vu_rng_guest_notifier_pending(VirtIODevice *vdev, int idx)
+{
+ VHostUserRNG *rng = vdev->vhrng;
+
+ /* return vhost_virtqueue_pending(&rng->vhost_dev, idx); */
+ return 1;
+}
+
+static void vu_rng_set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VHostUserRNG *rng = vdev->vhrng;
+ bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
+
+ if (rng->vhost_dev->started == should_start) {
+ DBG("rng->vhost_dev->started != should_start\n");
+ return;
+ }
+
+ if (should_start) {
+ vu_rng_start(vdev);
+ } else {
+ DBG("vu_rng_stop(vdev)\n");
+ /* TODO: Add vu_rng_stop(vdev); when this function is implemented */
+ }
+}
+
+static void virtio_dev_class_init(VirtIODevice *vdev)
+{
+ vdev->vdev_class = (VirtioDeviceClass *)malloc(sizeof(VirtioDeviceClass));
+ vdev->vdev_class->parent = vdev;
+ vdev->vdev_class->set_status = vu_rng_set_status;
+ vdev->vdev_class->get_features = vu_rng_get_features;
+ vdev->vdev_class->guest_notifier_mask = vu_rng_guest_notifier_mask;
+ vdev->vdev_class->guest_notifier_pending = vu_rng_guest_notifier_pending;
+ vdev->vdev_class->update_mem_table = update_mem_table;
+}
+
+
+void vhost_user_rng_init(VirtIODevice *vdev)
+{
+ VHostUserRNG *vhrng = (VHostUserRNG *)malloc(sizeof(VHostUserRNG));
+ vdev->vhrng = vhrng;
+ vdev->nvqs = &dev->nvqs;
+ vhrng->parent = vdev;
+ vhrng->req_vq = vdev->vq;
+ vhrng->vhost_dev = dev;
+
+ virtio_dev_class_init(vdev);
+ virtio_loopback_bus_init(vdev->vbus);
+}
+
+static void vu_rng_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ /*
+ * Not normally called; it's the daemon that handles the queue;
+ * however virtio's cleanup path can call this.
+ */
+ DBG("vu_rng_handle_output\n");
+}
+
+
+void vhost_user_rng_realize(void)
+{
+ /* Initiliaze virtio_dev data structures */
+ virtio_dev_init(global_vdev, "virtio-rng", 4, 0);
+
+ /* This needs to be change to vhost-user-rng init */
+ vhost_user_rng_init(global_vdev);
+
+ global_vdev->vq = virtio_add_queue(global_vdev, 4, vu_rng_handle_output);
+
+ global_vdev->host_features = 0x39000000;
+
+ proxy = (VirtIOMMIOProxy *)malloc(sizeof(VirtIOMMIOProxy));
+ *proxy = (VirtIOMMIOProxy) {
+ .legacy = 1,
+ };
+
+ /* Virtqueues conf */
+ dev->nvqs = 1;
+ dev->vqs = (struct vhost_virtqueue *)malloc(dev->nvqs *
+ sizeof(struct vhost_virtqueue));
+
+ /* Initiale vhost-user communication */
+ vhost_dev_init(dev);
+
+ /* Write the final features */
+ global_vdev->host_features = dev->features;
+ DBG("dev->host_features: 0x%lx\n", dev->features);
+}