diff options
author | 2024-10-01 18:16:29 +0300 | |
---|---|---|
committer | 2024-10-01 15:36:35 +0000 | |
commit | 9941dec970111be9e02dcaf6819c037946bde160 (patch) | |
tree | bea826b7fc861fe09c53d43f60d1a7d464e4cf9b /virtio_rng.c | |
parent | 1cc834724919caf5ea21c146b29f62b6cd213db7 (diff) |
Add multiple-device support virtio-loopback-adapter
Updates [v1]:
- The adapter supports multiple vhost-user devices running in
parallel.
- Redesign the devices interfaces. Unified their common functionality
and add it into vhost-user-loopback lib. This eases the addition of
new vhost-user devices and makes the virtio-loopback adapter more
device agnostic.
Bug-AGL: SPEC-4834
Change-Id: I9aff91dce0207ccdd8c2d1c5d0769a13b4e9ae04
Signed-off-by: Timos Ampelikiotis <t.ampelikiotis@virtualopensystems.com>
Diffstat (limited to 'virtio_rng.c')
-rw-r--r-- | virtio_rng.c | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/virtio_rng.c b/virtio_rng.c deleted file mode 100644 index f230b23..0000000 --- a/virtio_rng.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * A virtio device implementing a hardware random number generator. - * - * Based on virtio-rng.c of QEMU project - * Copyright 2012 Red Hat, Inc. - * Copyright 2012 Amit Shah <amit.shah@redhat.com> - * - * 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 - * top-level directory. - */ - -#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 "virtio_loopback.h" -#include "virtio_rng.h" - -#ifdef DEBUG -#define DBG(...) printf("virtio-rng: " __VA_ARGS__) -#else -#define DBG(...) -#endif /* DEBUG */ - -bool is_guest_ready(VirtIORNG *vrng) -{ - VirtIODevice *vdev = vrng->parent_obj; - - if (virtio_queue_ready(vrng->vq) - && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { - return true; - } - return false; -} - -size_t get_request_size(VirtQueue *vq, unsigned quota) -{ - unsigned int in, out; - - virtqueue_get_avail_bytes(vq, &in, &out, quota, 0); - return in; -} - -void virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) -{ - VirtIORNG *vrng = vdev->vrng; - - vdev->status = status; - - /* Something changed, try to process buffers */ - virtio_rng_process(vrng); -} - -/* Send data from a char device over to the guest */ -void chr_read(VirtIORNG *vrng, const void *buf, size_t size) -{ - VirtIODevice *vdev = vrng->parent_obj; - VirtQueueElement *elem; - size_t len, offset; - - if (!is_guest_ready(vrng)) { - return; - } - - vrng->quota_remaining -= size; - - offset = 0; - while (offset < size) { - elem = virtqueue_pop(vrng->vq, sizeof(VirtQueueElement)); - - - if (!elem) { - break; - } - len = qemu_iov_from_buf(elem->in_sg, elem->in_num, - 0, buf + offset, size - offset); - offset += len; - - virtqueue_push(vrng->vq, elem, len); - - /* - * TODO: We need tp free the elem - * - * g_free(elem); - */ - } - virtio_notify(vdev, vrng->vq); - - if (!virtio_queue_empty(vrng->vq)) { - /* - * If we didn't drain the queue, call virtio_rng_process - * to take care of asking for more data as appropriate. - */ - virtio_rng_process(vrng); - } -} - -const char test_str[64] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63}; - -void virtio_rng_process(VirtIORNG *vrng) -{ - size_t size; - unsigned quota; - - if (!is_guest_ready(vrng)) { - return; - } - - if (vrng->quota_remaining < 0) { - quota = 0; - } else { - quota = MIN((uint64_t)vrng->quota_remaining, (uint64_t)UINT32_MAX); - } - size = get_request_size(vrng->vq, quota); - size = MIN(vrng->quota_remaining, size); - - if (size) { - chr_read(vrng, &test_str, size); - } -} - -void handle_input(VirtIODevice *vdev, VirtQueue *vq) -{ - (void)vq; - virtio_rng_process(vdev->vrng); -} - -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 = virtio_rng_set_status; -} - -void virtio_rng_init(VirtIODevice *vdev) -{ - VirtIORNG *vrng = (VirtIORNG *)malloc(sizeof(VirtIORNG)); - vdev->vrng = vrng; - vrng->parent_obj = vdev; - vrng->vq = vdev->vq; - vrng->quota_remaining = LONG_MAX; - - /* Prepare dev_class */ - virtio_dev_class_init(vdev); -} - - -void virtio_rng_realize(int queue_num, int queue_size) -{ - (void)queue_num; - (void)queue_size; - - /* prepare procy and virtio dev*/ - proxy = (VirtIOMMIOProxy *)malloc(sizeof(VirtIOMMIOProxy)); - - virtio_dev_init(global_vdev, "virtio-rng", 4, 0); - - virtio_rng_init(global_vdev); - - global_vdev->vq = virtio_add_queue(global_vdev, 8, handle_input); - - global_vdev->host_features = 0x39000000; - - *proxy = (VirtIOMMIOProxy) { - .legacy = 1, - }; -} - |