aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--adapter.c20
-rw-r--r--event_notifier.c2
-rw-r--r--event_notifier.h2
-rw-r--r--vhost_loopback.c2
-rw-r--r--vhost_loopback.h2
-rw-r--r--vhost_user_blk.c2
-rw-r--r--vhost_user_blk.h2
-rw-r--r--vhost_user_gpio.c381
-rw-r--r--vhost_user_gpio.h37
-rw-r--r--vhost_user_input.c2
-rw-r--r--vhost_user_input.h2
-rw-r--r--vhost_user_loopback.c2
-rw-r--r--vhost_user_loopback.h2
-rw-r--r--vhost_user_rng.c2
-rw-r--r--vhost_user_rng.h2
-rw-r--r--virtio_input.c2
-rw-r--r--virtio_loopback.c112
-rw-r--r--virtio_loopback.h11
-rw-r--r--virtio_rng.c2
-rw-r--r--virtio_rng.h2
21 files changed, 489 insertions, 108 deletions
diff --git a/Makefile b/Makefile
index b02253f..3c596d1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# Copyright 2022 Virtual Open Systems SAS.
+# Copyright 2022-2023 Virtual Open Systems SAS
#
# Authors:
# Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
@@ -21,7 +21,7 @@
#CFLAGS := -Wall -Wextra -Werror
#CFLAGS := -Wall -Wextra -Wno-unused-variable -Wno-unused-function
CFLAGS := -Wno-unused-variable -Wno-unused-function -D_GNU_SOURCE
-CFLAGS = -D_GNU_SOURCE -O2 -static
+CFLAGS = -D_GNU_SOURCE -O2
CC ?=
ifeq ($(ARCH), arm64)
@@ -33,7 +33,7 @@ endif
INCL += -I .
DEPS = adapter.h vhost_user_loopback.h event_notifier.h virtio_loopback.h
-SRC_C = event_notifier.c vhost_user_loopback.c virtio_loopback.c virtio_rng.c virtio_input.c vhost_user_input.c vhost_user_blk.c vhost_user_rng.c vhost_loopback.c adapter.c
+SRC_C = event_notifier.c vhost_user_loopback.c virtio_loopback.c virtio_rng.c virtio_input.c vhost_user_input.c vhost_user_blk.c vhost_user_rng.c vhost_user_gpio.c vhost_loopback.c adapter.c
OBJS = $(SRC_C:.c=.o)
BINS = adapter
diff --git a/adapter.c b/adapter.c
index 25d9d4a..b95092c 100644
--- a/adapter.c
+++ b/adapter.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 2022-2023 Virtual Open Systems SAS
*
* Authors:
* Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
@@ -47,6 +47,7 @@
#include "vhost_user_rng.h"
#include "vhost_user_blk.h"
#include "vhost_user_input.h"
+#include "vhost_user_gpio.h"
#ifdef DEBUG
#define DBG(...) printf("adapter: " __VA_ARGS__)
@@ -137,7 +138,7 @@ static void help_args(void)
"\t\t [ -qn number of queues ]\n"
"\t\t [ -qs size of queues ]\n"
"The 'device_name' can be one of the following:\n"
- "\tvrng, vhurng, vhublk, vhuinput, vhusnd, vhugpio\n");
+ "\tvrng, vhurng, vhublk, vhuinput, vhugpio\n");
}
int find_arg(int argc, char **argv, char *str)
@@ -154,9 +155,10 @@ int find_arg(int argc, char **argv, char *str)
int val_device_arg(char *str)
{
- char *adapter_devices[] = {"vrng", "vhurng", "vhublk", "vhuinput"};
- char *vhu_devices[] = {"vhurng", "vhublk", "vhuinput"};
- int adapter_devices_num = 4, i;
+ char *adapter_devices[] = {"vrng", "vhurng", "vhublk", "vhuinput",
+ "vhugpio"};
+ char *vhu_devices[] = {"vhurng", "vhublk", "vhuinput", "vhugpio"};
+ int adapter_devices_num = 5, i;
for (i = 0; i < adapter_devices_num; i++) {
if (!strcmp(adapter_devices[i], str)) {
@@ -169,8 +171,8 @@ int val_device_arg(char *str)
bool check_vhu_device(char *str)
{
- char *vhu_devices[] = {"vhurng", "vhublk", "vhuinput"};
- int vhu_devices_num = 3, i;
+ char *vhu_devices[] = {"vhurng", "vhublk", "vhuinput", "vhugpio"};
+ int vhu_devices_num = 4, i;
for (i = 0; i < vhu_devices_num; i++) {
if (!strcmp(vhu_devices[i], str)) {
@@ -269,6 +271,7 @@ int main(int argc, char **argv)
vhost_user_adapter_init();
/* Initialize the virtio/vhost-user device */
+ /* TODO: Switch numbers with name defs */
switch (device_id) {
case 1:
virtio_rng_realize();
@@ -286,6 +289,9 @@ int main(int argc, char **argv)
vhost_user_input_init(global_vdev);
virtio_input_device_realize();
break;
+ case 5:
+ vu_gpio_device_realize();
+ break;
default:
exit(1);
}
diff --git a/event_notifier.c b/event_notifier.c
index 5a5d1c3..5b7c1cd 100644
--- a/event_notifier.c
+++ b/event_notifier.c
@@ -16,7 +16,7 @@
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2010 Red Hat, Inc.
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/event_notifier.h b/event_notifier.h
index 070b777..718f784 100644
--- a/event_notifier.h
+++ b/event_notifier.h
@@ -6,7 +6,7 @@
* Authors:
* Michael S. Tsirkin <mst@redhat.com>
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/vhost_loopback.c b/vhost_loopback.c
index 3e137eb..af725e3 100644
--- a/vhost_loopback.c
+++ b/vhost_loopback.c
@@ -11,7 +11,7 @@
* Authors:
* Michael S. Tsirkin <mst@redhat.com>
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/vhost_loopback.h b/vhost_loopback.h
index 78c2755..198a5af 100644
--- a/vhost_loopback.h
+++ b/vhost_loopback.h
@@ -1,7 +1,7 @@
/*
* Based on vhost.h of QEMU project
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/vhost_user_blk.c b/vhost_user_blk.c
index 756b0a5..d182a74 100644
--- a/vhost_user_blk.c
+++ b/vhost_user_blk.c
@@ -11,7 +11,7 @@
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
* Nicholas Bellinger <nab@risingtidesystems.com>
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * 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
diff --git a/vhost_user_blk.h b/vhost_user_blk.h
index 3b09f75..d5857c8 100644
--- a/vhost_user_blk.h
+++ b/vhost_user_blk.h
@@ -7,7 +7,7 @@
* Changpeng Liu <changpeng.liu@intel.com>
*
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/vhost_user_gpio.c b/vhost_user_gpio.c
new file mode 100644
index 0000000..6049bd5
--- /dev/null
+++ b/vhost_user_gpio.c
@@ -0,0 +1,381 @@
+/*
+ * Based on vhost-user-gpio.c of QEMU project
+ *
+ * Copyright (c) 2022 Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * Copyright (c) 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>
+#include <errno.h>
+
+/* Project header files */
+#include "vhost_user_gpio.h"
+
+#ifdef DEBUG
+#define DBG(...) printf("vhost-user-gpio: " __VA_ARGS__)
+#else
+#define DBG(...)
+#endif /* DEBUG */
+
+#define REALIZE_CONNECTION_RETRIES 3
+#define VHOST_NVQS 2
+
+static const int feature_bits[] = {
+ VIRTIO_F_VERSION_1,
+ VIRTIO_F_NOTIFY_ON_EMPTY,
+ VIRTIO_RING_F_INDIRECT_DESC,
+ VIRTIO_RING_F_EVENT_IDX,
+ VIRTIO_GPIO_F_IRQ,
+ VIRTIO_F_RING_RESET,
+ VHOST_INVALID_FEATURE_BIT
+};
+
+static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VHostUserGPIO *gpio = dev->vdev->vhugpio;
+
+ DBG("vu_gpio_get_config()\n");
+ memcpy(config, &gpio->config, sizeof(gpio->config));
+}
+
+static int vu_gpio_config_notifier(struct vhost_dev *dev)
+{
+ VHostUserGPIO *gpio = dev->vdev->vhugpio;
+
+ DBG("vu_gpio_config_notifier\n");
+
+ memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
+ virtio_notify_config(dev->vdev);
+
+ return 0;
+}
+
+const VhostDevConfigOps gpio_ops = {
+ .vhost_dev_config_notifier = vu_gpio_config_notifier,
+};
+
+static int vu_gpio_start(VirtIODevice *vdev)
+{
+ VirtioBus *k = vdev->vbus;
+ VHostUserGPIO *gpio = vdev->vhugpio;
+ int ret, i;
+
+ DBG("vu_gpio_start()\n");
+
+ if (!k->set_guest_notifiers) {
+ DBG("binding does not support guest notifiers");
+ return -ENOSYS;
+ }
+
+ ret = vhost_dev_enable_notifiers(gpio->vhost_dev, vdev);
+ if (ret < 0) {
+ DBG("Error enabling host notifiers: %d", ret);
+ return ret;
+ }
+
+ ret = k->set_guest_notifiers(k->vdev, gpio->vhost_dev->nvqs, true);
+ if (ret < 0) {
+ DBG("Error binding guest notifier: %d", ret);
+ goto out_with_err_host_notifiers;
+ }
+
+ vhost_ack_features(gpio->vhost_dev, feature_bits, vdev->guest_features);
+
+ ret = vhost_dev_start(gpio->vhost_dev, vdev, true);
+ if (ret < 0) {
+ DBG("Error starting vhost-user-gpio: %d", ret);
+ goto out_with_err_guest_notifiers;
+ }
+ gpio->started_vu = true;
+
+ for (i = 0; i < gpio->vhost_dev->nvqs; i++) {
+ vhost_virtqueue_mask(gpio->vhost_dev, vdev, i, false);
+ }
+
+ /*
+ * TODO: check if we need the following is needed
+ * ret = gpio->vhost_dev->vhost_ops->vhost_set_vring_enable(gpio->vhost_dev,
+ * true);
+ */
+
+ return 0;
+
+out_with_err_guest_notifiers:
+ k->set_guest_notifiers(k->vdev, gpio->vhost_dev->nvqs, false);
+out_with_err_host_notifiers:
+ /*
+ * TODO: implement the following functions:
+ * vhost_dev_disable_notifiers(&gpio->vhost_dev, vdev);
+ */
+
+ return ret;
+}
+
+static void vu_gpio_stop(VirtIODevice *vdev)
+{
+ DBG("vu_gpio_stop() not yet implemented\n");
+}
+
+static void vu_gpio_set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VHostUserGPIO *gpio = vdev->vhugpio;
+ bool should_start = virtio_device_started(vdev, status);
+
+ DBG("vu_gpio_set_status()\n");
+
+ if (!gpio->connected) {
+ return;
+ }
+
+printf("should_start: %d\n", should_start);
+ if (gpio->vhost_dev->started) {
+ return;
+ }
+
+ if (should_start) {
+ if (vu_gpio_start(vdev)) {
+ DBG("vu_gpio_start() failed\n");
+ }
+ } else {
+ vu_gpio_stop(vdev);
+ }
+}
+
+static uint64_t vu_gpio_get_features(VirtIODevice *vdev, uint64_t features)
+{
+ VHostUserGPIO *gpio = vdev->vhugpio;
+
+ DBG("vu_gpio_get_features()\n");
+ return vhost_get_features(gpio->vhost_dev, feature_bits, features);
+}
+
+static void vu_gpio_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_gpio_handle_output not yet implemented\n");
+}
+
+static void vu_gpio_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
+{
+ VHostUserGPIO *gpio = vdev->vhugpio;
+
+ DBG("vu_gpio_guest_notifier_mask() not yet implemented\n");
+
+ vhost_virtqueue_mask(gpio->vhost_dev, vdev, idx, mask);
+}
+
+static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserGPIO *gpio)
+{
+ DBG("do_vhost_user_cleanup() not yet implemented\n");
+}
+
+static int vu_gpio_connect(VirtIODevice *vdev)
+{
+ VHostUserGPIO *gpio = vdev->vhugpio;
+ int ret;
+
+ DBG("vu_gpio_connect()\n");
+
+ if (gpio->connected) {
+ return 0;
+ }
+ gpio->connected = true;
+
+ vhost_dev_set_config_notifier(gpio->vhost_dev, &gpio_ops);
+ /*
+ * TODO: Investigate if the following is needed
+ * gpio->vhost_user.supports_config = true;
+ */
+
+ gpio->vhost_dev->nvqs = VHOST_NVQS;
+ gpio->vhost_dev->vqs = gpio->vhost_vqs;
+
+ vhost_dev_init(gpio->vhost_dev);
+ /*
+ * TODO: Add error handling
+ * if (ret < 0) {
+ * return ret;
+ * }
+ */
+
+ /* restore vhost state */
+ if (virtio_device_started(vdev, vdev->status)) {
+ vu_gpio_start(vdev);
+ }
+
+ return 0;
+}
+
+static int vu_gpio_realize_connect(VHostUserGPIO *gpio)
+{
+ int ret;
+
+ DBG("vu_gpio_realize_connect()\n");
+
+ ret = vu_gpio_connect(gpio->parent);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = vhost_dev_get_config(gpio->vhost_dev, (uint8_t *)&gpio->config,
+ sizeof(gpio->config));
+
+ if (ret < 0) {
+ DBG("vhost-user-gpio: get config failed\n");
+ /*
+ * TODO: Add cleanup function
+ * vhost_dev_cleanup(vhost_dev);
+ */
+ return ret;
+ }
+
+ return 0;
+}
+
+static void vu_gpio_device_unrealize(VirtIODevice *vdev)
+{
+ DBG("vu_gpio_device_unrealize() not yet implemented\n");
+}
+
+static void print_config_gpio(uint8_t *config_data)
+{
+ struct virtio_gpio_config *config =
+ (struct virtio_gpio_config *)config_data;
+
+ DBG("ngpio: %hu\n", config->ngpio);
+ DBG("gpio_names_size: %u\n", config->gpio_names_size);
+}
+
+static void vu_gpio_class_init(VirtIODevice *vdev)
+{
+ DBG("vu_gpio_class_init()\n");
+
+ vdev->vdev_class = (VirtioDeviceClass *)malloc(sizeof(VirtioDeviceClass));
+ if (!vdev->vdev_class) {
+ DBG("vdev_class memory allocation failed\n");
+ return;
+ }
+ vdev->vdev_class->realize = vu_gpio_device_realize;
+ vdev->vdev_class->unrealize = vu_gpio_device_unrealize;
+ vdev->vdev_class->get_features = vu_gpio_get_features;
+ vdev->vdev_class->get_config = vu_gpio_get_config;
+ vdev->vdev_class->set_status = vu_gpio_set_status;
+ vdev->vdev_class->guest_notifier_mask = vu_gpio_guest_notifier_mask;
+}
+
+void vu_gpio_init(VirtIODevice *vdev)
+{
+ DBG("vu_gpio_init()\n");
+
+ VHostUserGPIO *vhugpio = (VHostUserGPIO *)malloc(sizeof(VHostUserGPIO));
+ if (!proxy) {
+ DBG("proxy memory allocation failed\n");
+ goto out;
+ }
+
+ vdev->vhugpio = vhugpio;
+ vdev->nvqs = &dev->nvqs;
+ vhugpio->parent = vdev;
+ vhugpio->vhost_dev = dev;
+
+ vu_gpio_class_init(vdev);
+ virtio_loopback_bus_init(vdev->vbus);
+
+out:
+ return;
+}
+
+/* TODO: Add queue_num, queue_size as parameters */
+void vu_gpio_device_realize()
+{
+ int retries, ret;
+ int i;
+
+ DBG("vu_gpio_device_realize()\n");
+
+ /* This needs to be added */
+ proxy = (VirtIOMMIOProxy *)malloc(sizeof(VirtIOMMIOProxy));
+ if (!proxy) {
+ DBG("proxy memory allocation failed\n");
+ goto out_with_error;
+ }
+
+ *proxy = (VirtIOMMIOProxy) {
+ .legacy = 1,
+ };
+
+ /* VIRTIO_ID_GPIO is 41, check virtio_ids.h in linux */
+ virtio_dev_init(global_vdev, "virtio-gpio", 41,
+ sizeof(struct virtio_gpio_config));
+
+ vu_gpio_init(global_vdev);
+ if (!global_vdev->vhugpio) {
+ DBG("vhugpio memory allocation failed\n");
+ goto out_with_proxy;
+ }
+
+ global_vdev->vhugpio->command_vq = virtio_add_queue(global_vdev, 64,
+ vu_gpio_handle_output);
+ global_vdev->vhugpio->interrupt_vq = virtio_add_queue(global_vdev, 64,
+ vu_gpio_handle_output);
+
+ global_vdev->vhugpio->vhost_vqs = (struct vhost_virtqueue *)
+ malloc(sizeof(struct vhost_virtqueue *));
+ if (!global_vdev->vhugpio->vhost_vqs) {
+ DBG("vhost_vqs memory allocation failed\n");
+ goto out_with_dev;
+ }
+
+ global_vdev->vhugpio->connected = false;
+
+ retries = REALIZE_CONNECTION_RETRIES;
+
+ do {
+ ret = vu_gpio_realize_connect(global_vdev->vhugpio);
+ } while (ret < 0 && retries--);
+
+ if (ret < 0) {
+ DBG("vu_gpio_realize_connect(): -EPROTO\n");
+ do_vhost_user_cleanup(global_vdev, global_vdev->vhugpio);
+ }
+
+ print_config_gpio((uint8_t *)(&global_vdev->vhugpio->config));
+ DBG("(realize completed)\n");
+
+ return;
+
+ /* TODO: Fix the following considering also do_vhost_user_cleanup() */
+out_with_cmd_vq:
+ /* free(global_vdev->vhugpio->command_vq); */
+out_with_dev:
+ free(global_vdev->vhugpio);
+out_with_proxy:
+ free(proxy);
+out_with_error:
+ DBG("Realize funciton return error\n");
+ return;
+}
diff --git a/vhost_user_gpio.h b/vhost_user_gpio.h
new file mode 100644
index 0000000..4477ba7
--- /dev/null
+++ b/vhost_user_gpio.h
@@ -0,0 +1,37 @@
+/*
+ * Based on virtio-gpio.h of QEMU project
+ *
+ * Copyright (c) 2023 Virtual Open Systems SAS.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the
+ * top-level directory.
+ */
+
+#ifndef VHOST_USER_GPIO
+#define VHOST_USER_GPIO
+
+#include "vhost_loopback.h"
+#include "vhost_user_loopback.h"
+#include "virtio_loopback.h"
+#include <linux/virtio_gpio.h>
+#include "queue.h"
+#include <sys/mman.h>
+
+#define TYPE_VHOST_USER_GPIO "vhost-user-gpio-device"
+#define VIRTIO_GPIO_F_IRQ 0
+
+struct VHostUserGPIO {
+ VirtIODevice *parent;
+ struct virtio_gpio_config config;
+ struct vhost_virtqueue *vhost_vqs;
+ struct vhost_dev *vhost_dev;
+ VirtQueue *command_vq;
+ VirtQueue *interrupt_vq;
+ bool connected;
+ bool started_vu;
+};
+
+void vu_gpio_device_realize();
+
+#endif /* VHOST_USER_GPIO */
diff --git a/vhost_user_input.c b/vhost_user_input.c
index d6764cc..9cb2164 100644
--- a/vhost_user_input.c
+++ b/vhost_user_input.c
@@ -1,7 +1,7 @@
/*
* Based on vhost-user-input.c of QEMU project
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* (at your option) any later version. See the COPYING file in the
diff --git a/vhost_user_input.h b/vhost_user_input.h
index 0d5c900..741006e 100644
--- a/vhost_user_input.h
+++ b/vhost_user_input.h
@@ -1,7 +1,7 @@
/*
* Based on virtio-input.h of QEMU project
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* (at your option) any later version. See the COPYING file in the
diff --git a/vhost_user_loopback.c b/vhost_user_loopback.c
index 47ce1cd..85b9405 100644
--- a/vhost_user_loopback.c
+++ b/vhost_user_loopback.c
@@ -9,7 +9,7 @@
* Marc-André Lureau <mlureau@redhat.com>
* Victor Kaplansky <victork@redhat.com>
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/vhost_user_loopback.h b/vhost_user_loopback.h
index 2ced983..8aa7e05 100644
--- a/vhost_user_loopback.h
+++ b/vhost_user_loopback.h
@@ -7,7 +7,7 @@
* Victor Kaplansky <victork@redhat.com>
* Marc-André Lureau <mlureau@redhat.com>
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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
diff --git a/vhost_user_rng.c b/vhost_user_rng.c
index 6d4fd5c..c727636 100644
--- a/vhost_user_rng.c
+++ b/vhost_user_rng.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2021 Mathieu Poirier <mathieu.poirier@linaro.org>
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * 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
diff --git a/vhost_user_rng.h b/vhost_user_rng.h
index fd39800..69b5916 100644
--- a/vhost_user_rng.h
+++ b/vhost_user_rng.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2021 Mathieu Poirier <mathieu.poirier@linaro.org>
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
*
* Author:
* Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
diff --git a/virtio_input.c b/virtio_input.c
index 18ef3d4..c0993ea 100644
--- a/virtio_input.c
+++ b/virtio_input.c
@@ -1,7 +1,7 @@
/*
* Based on virtio-input.h of QEMU project
*
- * Copyright (c) 2022 Virtual Open Systems SAS.
+ * Copyright (c) 2022-2023 Virtual Open Systems SAS.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* (at your option) any later version. See the COPYING file in the
diff --git a/virtio_loopback.c b/virtio_loopback.c
index f9e5464..e95c648 100644
--- a/virtio_loopback.c
+++ b/virtio_loopback.c
@@ -18,7 +18,7 @@
* Peter Maydell <peter.maydell@linaro.org>
*
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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; either version 2
@@ -80,6 +80,9 @@ virtio_neg_t *address;
VirtIOMMIOProxy *proxy;
+int eventfd_count;
+pthread_mutex_t interrupt_lock;
+
void virtio_add_feature(uint64_t *features, unsigned int fbit)
{
*features |= (1ULL << fbit);
@@ -860,9 +863,9 @@ err:
void print_neg_flag(uint64_t neg_flag, bool read)
{
if (read) {
- DBG("Read:\n");
+ DBG("Read:\t");
} else {
- DBG("Write:\n");
+ DBG("Write:\t");
}
switch (neg_flag) {
@@ -1005,8 +1008,6 @@ static void virtio_queue_guest_notifier_read(EventNotifier *n)
}
}
-int eventfd_count;
-
void *loopback_event_select(void *_e)
{
int retval;
@@ -1032,14 +1033,19 @@ void *loopback_event_select(void *_e)
if (retval > 0) {
DBG("\n\nEvent has come from the vhost-user-device "
- "(eventfd: %d) -> event_count: %d\n\n",
- rfd, eventfd_count);
+ "(eventfd: %d) -> event_count: %d (select value: %d)\n\n",
+ rfd, eventfd_count, retval);
- eventfd_count++;
if (event_notifier_test_and_clear(e)) {
- virtio_irq(vq);
+ if (pthread_mutex_lock(&interrupt_lock) == 0) {
+ eventfd_count++;
+ virtio_irq(vq);
+ pthread_mutex_unlock(&interrupt_lock);
+ } else {
+ printf("[ERROR] Locking failed\n");
+ exit(1);
+ }
}
-
}
}
}
@@ -1226,7 +1232,7 @@ void virtio_loopback_update_irq(VirtIODevice *vdev)
DBG("prev_level: %d\n", prev_level);
if (!((level == 1) && (prev_level == 0))) {
- DBG("!((level == 1) && (prev_level == 0))\n");
+ DBG("No interrupt\n");
prev_level = level;
return;
}
@@ -1236,7 +1242,6 @@ void virtio_loopback_update_irq(VirtIODevice *vdev)
DBG("Interrupt counter: %d\n", int_count++);
(void) ioctl(fd, IRQ, &irq_num);
-
}
bool enable_virtio_interrupt;
@@ -1280,7 +1285,6 @@ void virtio_queue_notify(VirtIODevice *vdev, int n)
}
if (vq->host_notifier_enabled) {
- DBG("vq->host_notifier_enabled\n");
event_notifier_set(&vq->host_notifier);
} else if (vq->handle_output) {
DBG("vq->handle_output\n");
@@ -1397,8 +1401,6 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
uint64_t ret;
- DBG("READ\n");
-
if (!vdev) {
/*
* If no backend is present, we treat most registers as
@@ -1545,14 +1547,13 @@ static uint64_t virtio_loopback_read(VirtIODevice *vdev, uint64_t offset,
return 0;
}
-uint64_t vring_phys_addrs[2] = {0};
+uint64_t vring_phys_addrs[10] = {0};
uint32_t vring_phys_addrs_idx;
static int notify_cnt;
void virtio_loopback_write(VirtIODevice *vdev, uint64_t offset,
uint64_t value, unsigned size)
{
-
if (!vdev) {
/*
* If no backend is present, we just make all registers
@@ -1690,7 +1691,7 @@ void virtio_loopback_write(VirtIODevice *vdev, uint64_t offset,
/* TODO: To be implemented */
break;
case VIRTIO_MMIO_QUEUE_NOTIFY:
- DBG("\nVIRTIO_MMIO_QUEUE_NOTIFY: vq_index -> %d, notify_cnt: %d\n",
+ DBG("VIRTIO_MMIO_QUEUE_NOTIFY: vq_index -> %d, notify_cnt: %d\n",
value, notify_cnt++);
if (value < VIRTIO_QUEUE_MAX) {
virtio_queue_notify(vdev, value);
@@ -1824,39 +1825,6 @@ void adapter_read_write_cb(void)
}
-void *notify_select(void *data)
-{
- int retval;
- fd_set rfds;
- uint64_t eftd_ctr;
- int efd = *(int *)data;
- int32_t vq_index;
-
- DBG("\nWaiting for loopback notify events\n");
-
- FD_ZERO(&rfds);
- FD_SET(efd, &rfds);
-
- while (1) {
-
- retval = select(efd + 1, &rfds, NULL, NULL, NULL);
-
- if (retval > 0) {
- s = read(efd, &eftd_ctr, sizeof(uint64_t));
- if (s != sizeof(uint64_t)) {
- DBG("Eventfd read error\n");
- exit(1);
- } else {
- DBG("\nnotify select\n");
- (void)ioctl(fd, SHARE_NOTIFIED_VQ_INDEX, &vq_index);
- DBG("\nnotify_select: vq_index -> %d, notify_cnt: %d,"
- "eventfd_val: %lu\n\n", vq_index, notify_cnt++, eftd_ctr);
- virtio_queue_notify(global_vdev, vq_index);
- }
- }
- }
-}
-
void *driver_event_select(void *data)
{
int retval;
@@ -1937,6 +1905,20 @@ void virtio_dev_init(VirtIODevice *vdev, const char *name,
DBG("virtio_dev_init\n");
+ /* Initialize global variables */
+ prev_level = 0;
+ int_count = 0;
+ eventfd_count = 0;
+ enable_virtio_interrupt = false;
+ vring_phys_addrs_idx = 0;
+ notify_cnt = 0;
+
+ /* Initialize interrupt mutex */
+ if (pthread_mutex_init(&interrupt_lock, NULL) != 0) {
+ printf("[ERROR] mutex init has failed\n");
+ exit(1);
+ }
+
vdev->start_on_kick = false;
vdev->started = false;
vdev->device_id = device_id;
@@ -2004,18 +1986,9 @@ int virtio_loopback_start(void)
{
efd_data_t info;
pthread_t thread_id;
- pthread_t thread_id_notify;
int ret = -1;
int flags;
- /* Initialize global variables */
- prev_level = 0;
- int_count = 0;
- eventfd_count = 0;
- enable_virtio_interrupt = false;
- vring_phys_addrs_idx = 0;
- notify_cnt = 0;
-
fd = open("/dev/loopback", O_RDWR);
if (fd < 0) {
perror("Open call failed");
@@ -2030,15 +2003,8 @@ int virtio_loopback_start(void)
exit(EXIT_FAILURE);
}
- efd_notify = eventfd(0, 0);
- if (efd_notify == -1) {
- DBG("\nUnable to create eventfd! Exiting...\n");
- exit(EXIT_FAILURE);
- }
-
info.pid = getpid();
info.efd[0] = efd;
- info.efd[1] = efd_notify;
/*
* Send the appropriate information to the driver
@@ -2060,13 +2026,6 @@ int virtio_loopback_start(void)
exit(1);
}
- /* Wait the eventfd */
- ret = pthread_create(&thread_id_notify, NULL, notify_select,
- (void *)&efd_notify);
- if (ret != 0) {
- exit(1);
- }
-
/* Start loopback transport */
(void)ioctl(fd, START_LOOPBACK, &device_info);
@@ -2075,11 +2034,6 @@ int virtio_loopback_start(void)
exit(1);
}
- ret = pthread_join(thread_id_notify, NULL);
- if (ret != 0) {
- exit(1);
- }
-
DBG("\nClosing eventfd. Exiting...\n");
close(efd);
diff --git a/virtio_loopback.h b/virtio_loopback.h
index 849f3a9..34bae2f 100644
--- a/virtio_loopback.h
+++ b/virtio_loopback.h
@@ -16,7 +16,7 @@
*
* 3) vhost.h of QEMU project
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 2022-2023 Virtual Open Systems SAS.
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
@@ -167,7 +167,6 @@
#define SHARE_VQS _IOC(_IOC_WRITE, 'k', 5, sizeof(uint32_t))
#define SHARE_BUF _IOC(_IOC_WRITE, 'k', 6, sizeof(uint64_t))
#define SHARE_COM_STRUCT _IOC(_IOC_WRITE, 'k', 7, 0)
-#define SHARE_NOTIFIED_VQ_INDEX _IOC(_IOC_WRITE, 'k', 8, sizeof(int32_t))
#define VIRTIO_PCI_VRING_ALIGN 4096
@@ -261,7 +260,7 @@ typedef struct VirtIOMMIOProxy {
const typeof(((type *) 0)->member) *__mptr = (ptr); \
(type *) ((char *) __mptr - offsetof(type, member));})
-extern uint64_t vring_phys_addrs[2];
+extern uint64_t vring_phys_addrs[10];
extern uint32_t vring_phys_addrs_idx;
typedef struct VRing {
@@ -363,6 +362,8 @@ typedef struct VHostUserRNG VHostUserRNG;
typedef struct VirtioDeviceClass VirtioDeviceClass;
typedef struct VHostUserBlk VHostUserBlk;
typedef struct VhostUserInput VhostUserInput;
+typedef struct VHostUserGPIO VHostUserGPIO;
+typedef struct VHostUserSound VHostUserSound;
typedef struct VirtioBus VirtioBus;
typedef struct VirtIODevice {
@@ -402,6 +403,8 @@ typedef struct VirtIODevice {
VHostUserRNG *vhrng;
VHostUserBlk *vhublk;
VhostUserInput *vhuinput;
+ VHostUserSound *vhusnd;
+ VHostUserGPIO *vhugpio;
} VirtIODevice;
typedef struct efd_data {
@@ -690,7 +693,7 @@ uint32_t get_vqs_max_size(VirtIODevice *vdev);
* memory blocks from the kernel:
* 0x40000000 = 1024 * 1024 * 1024 = 64 * 4096 * 4096 = 1G
*/
-#define OFFSET_1GB 64ULL * PAGE_SIZE * PAGE_SIZE
+#define OFFSET_1GB (64ULL * PAGE_SIZE * PAGE_SIZE)
/*
* Define starting physical address of host memory address space
diff --git a/virtio_rng.c b/virtio_rng.c
index ca8f971..6a5b24b 100644
--- a/virtio_rng.c
+++ b/virtio_rng.c
@@ -5,7 +5,7 @@
* Copyright 2012 Red Hat, Inc.
* Copyright 2012 Amit Shah <amit.shah@redhat.com>
*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 2022-2023 Virtual Open Systems SAS.
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* (at your option) any later version. See the COPYING file in the
diff --git a/virtio_rng.h b/virtio_rng.h
index 8147864..cf35c29 100644
--- a/virtio_rng.h
+++ b/virtio_rng.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 Virtual Open Systems SAS.
+ * Copyright 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