[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Minios-devel] [UNIKRAFT PATCH 03/12] plat/drivers: Init virtio block device



This patch introduces the initialization of virtio block device.
First, the driver sets what features supports, and then the driver
negotiates with the device for the common features.

Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
---
 plat/drivers/include/virtio/virtio_blk.h | 39 ++++++++++++++
 plat/drivers/virtio/virtio_blk.c         | 89 ++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+)
 create mode 100644 plat/drivers/include/virtio/virtio_blk.h

diff --git a/plat/drivers/include/virtio/virtio_blk.h 
b/plat/drivers/include/virtio/virtio_blk.h
new file mode 100644
index 00000000..b4b566e2
--- /dev/null
+++ b/plat/drivers/include/virtio/virtio_blk.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
+ *
+ * Copyright (c) 2019, University Politehnica of Bucharest.
+ *
+ * Permission to use, copy, modify, and/or distribute this software
+ * for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear
+ * in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __PLAT_DRV_VIRTIO_BLK_H
+#define __PLAT_DRV_VIRTIO_BLK_H
+#include <uk/config.h>
+#include <uk/arch/types.h>
+
+/* Device is read-only. */
+#define VIRTIO_BLK_F_RO                5
+/* Block size of disk is in blk_size. */
+#define VIRTIO_BLK_F_BLK_SIZE  6
+
+struct virtio_blk_config {
+       /* Dimension in sectors number */
+       __u64 capacity;
+       /* Block size */
+       __u32 blk_size;
+};
+
+#endif /* __PLAT_DRV_VIRTIO_BLK_H */
diff --git a/plat/drivers/virtio/virtio_blk.c b/plat/drivers/virtio/virtio_blk.c
index 91e8bf1c..b01b39bd 100644
--- a/plat/drivers/virtio/virtio_blk.c
+++ b/plat/drivers/virtio/virtio_blk.c
@@ -28,13 +28,22 @@
 #include <virtio/virtio_bus.h>
 #include <virtio/virtio_ids.h>
 #include <uk/blkdev.h>
+#include <virtio/virtio_blk.h>
 #include <uk/blkdev_driver.h>
 
 #define DRIVER_NAME            "virtio-blk"
+#define DEFAULT_SECTOR_SIZE    512
 
 #define to_virtioblkdev(bdev) \
        __containerof(bdev, struct virtio_blk_device, blkdev)
 
+/* Features are:
+ *     Access Mode
+ *     Sector_size;
+ **/
+#define VIRTIO_BLK_DRV_FEATURES(features) \
+       (VIRTIO_FEATURES_UPDATE(features, VIRTIO_BLK_F_RO | \
+       VIRTIO_BLK_F_BLK_SIZE))
 
 static struct uk_alloc *a;
 static const char *drv_name = DRIVER_NAME;
@@ -44,6 +53,10 @@ struct virtio_blk_device {
        struct uk_blkdev blkdev;
        /* The blkdevice identifier */
        __u16 uid;
+       /* Virtio Device */
+       struct virtio_dev *vdev;
+};
+
 };
 
 static void virtio_blkdev_close(struct uk_blkdev *dev)
@@ -60,6 +73,72 @@ static void virtio_blkdev_close(struct uk_blkdev *dev)
        uk_pr_info(DRIVER_NAME": %"__PRIu16" closed\n", uid);
 }
 
+
+static int virtio_blkdev_feature_negotiate(struct virtio_blk_device *vbdev)
+{
+       struct uk_blkdev_cap *cap;
+       __u64 host_features = 0;
+       int rc = 0;
+       int bytes_to_read;
+       __sector sectors;
+       __sector ssize;
+
+       UK_ASSERT(vbdev);
+       cap = &vbdev->blkdev.capabilities;
+       host_features = virtio_feature_get(vbdev->vdev);
+
+       /* Get size of device */
+       bytes_to_read = virtio_config_get(vbdev->vdev,
+                       __offsetof(struct virtio_blk_config, capacity),
+                       &sectors,
+                       sizeof(sectors),
+                       1);
+       if (bytes_to_read != sizeof(sectors))  {
+               uk_pr_err("Failed to get nb of sectors from device %d\n", rc);
+               rc = -EAGAIN;
+               goto exit;
+       }
+
+       if (!virtio_has_features(host_features, VIRTIO_BLK_F_BLK_SIZE)) {
+               ssize = DEFAULT_SECTOR_SIZE;
+       } else {
+               bytes_to_read = virtio_config_get(vbdev->vdev,
+                               __offsetof(struct virtio_blk_config, blk_size),
+                               &ssize,
+                               sizeof(ssize),
+                               1);
+               if (bytes_to_read != sizeof(ssize))  {
+                       uk_pr_err("Failed to get ssize from the device %d\n",
+                                       rc);
+                       rc = -EAGAIN;
+                       goto exit;
+               }
+       }
+
+       cap->ssize = ssize;
+       cap->sectors = sectors;
+       cap->align = sizeof(void *);
+       cap->mode = (virtio_has_features(
+                       host_features, VIRTIO_BLK_F_RO)) ? O_RDONLY : O_RDWR;
+
+       /**
+        * Mask out features supported by both driver and device.
+        */
+       vbdev->vdev->features &= host_features;
+       virtio_feature_set(vbdev->vdev, vbdev->vdev->features);
+
+exit:
+       return rc;
+}
+
+static inline void virtio_blkdev_feature_set(struct virtio_blk_device *vbdev)
+{
+       vbdev->vdev->features = 0;
+
+       /* Setting the feature the driver support */
+       VIRTIO_BLK_DRV_FEATURES(vbdev->vdev->features);
+}
+
 static const struct uk_blkdev_ops virtio_blkdev_ops = {
                .dev_close = virtio_blkdev_close,
 };
@@ -75,6 +154,7 @@ static int virtio_blk_add_dev(struct virtio_dev *vdev)
        if (!vbdev)
                return -ENOMEM;
 
+       vbdev->vdev = vdev;
        vbdev->blkdev.dev_ops = &virtio_blkdev_ops;
 
        rc = uk_blkdev_drv_register(&vbdev->blkdev, a, drv_name);
@@ -84,10 +164,19 @@ static int virtio_blk_add_dev(struct virtio_dev *vdev)
        }
 
        vbdev->uid = rc;
+       virtio_blkdev_feature_set(vbdev);
+       rc = virtio_blkdev_feature_negotiate(vbdev);
+       if (rc) {
+               uk_pr_err("Failed to negotiate the device feature %d\n", rc);
+               goto err_negotiate_feature;
+       }
+
        uk_pr_info("Virtio-blk device registered with libukblkdev\n");
 
 out:
        return rc;
+err_negotiate_feature:
+       virtio_dev_status_update(vbdev->vdev, VIRTIO_CONFIG_STATUS_FAIL);
 err_out:
        uk_free(a, vbdev);
        goto out;
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.