All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anastasiia Lukianenko <vicooodin@gmail.com>
To: u-boot@lists.denx.de
Subject: [RESEND PATCH v2 14/18] xen: pvblock: Read XenStore configuration and initialize
Date: Thu,  6 Aug 2020 12:42:57 +0300	[thread overview]
Message-ID: <20200806094301.4999-15-vicooodin@gmail.com> (raw)
In-Reply-To: <20200806094301.4999-1-vicooodin@gmail.com>

From: Anastasiia Lukianenko <anastasiia_lukianenko@epam.com>

Read essential virtual block device configuration data from XenStore,
initialize front ring and event channel.
Update block device description with actual block size.

Use code for XenStore from mini-os.

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Signed-off-by: Anastasiia Lukianenko <anastasiia_lukianenko@epam.com>
---

Changes since v1:
 - add comments
 - correct code style

 drivers/xen/pvblock.c | 285 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 284 insertions(+), 1 deletion(-)

diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 3ed62cac5d..e247ce33a3 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
+ * (C) 2007-2008 Samuel Thibault.
  * (C) Copyright 2020 EPAM Systems Inc.
  */
 #include <blk.h>
@@ -9,26 +10,302 @@
 #include <malloc.h>
 #include <part.h>
 
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/xen/system.h>
+
+#include <linux/compat.h>
+
+#include <xen/events.h>
+#include <xen/gnttab.h>
+#include <xen/hvm.h>
 #include <xen/xenbus.h>
 
+#include <xen/interface/io/ring.h>
+#include <xen/interface/io/blkif.h>
+#include <xen/interface/io/protocols.h>
+
 #define DRV_NAME	"pvblock"
 #define DRV_NAME_BLK	"pvblock_blk"
 
+#define O_RDONLY	00
+#define O_RDWR		02
+
+struct blkfront_info {
+	u64 sectors;
+	unsigned int sector_size;
+	int mode;
+	int info;
+	int barrier;
+	int flush;
+};
+
+/**
+ * struct blkfront_dev - Struct representing blkfront device
+ * @dom: Domain id
+ * @ring: Front_ring structure
+ * @ring_ref: The grant reference, allowing us to grant access
+ *	      to the ring to the other end/domain
+ * @evtchn: Event channel used to signal ring events
+ * @handle: Events handle
+ * @nodename: Device XenStore path in format "device/vbd/" + @devid
+ * @backend: Backend XenStore path
+ * @info: Private data
+ * @devid: Device id
+ */
 struct blkfront_dev {
-	char dummy;
+	domid_t dom;
+
+	struct blkif_front_ring ring;
+	grant_ref_t ring_ref;
+	evtchn_port_t evtchn;
+	blkif_vdev_t handle;
+
+	char *nodename;
+	char *backend;
+	struct blkfront_info info;
+	unsigned int devid;
 };
 
 struct blkfront_platdata {
 	unsigned int devid;
 };
 
+static void free_blkfront(struct blkfront_dev *dev)
+{
+	mask_evtchn(dev->evtchn);
+	free(dev->backend);
+
+	gnttab_end_access(dev->ring_ref);
+	free(dev->ring.sring);
+
+	unbind_evtchn(dev->evtchn);
+
+	free(dev->nodename);
+	free(dev);
+}
+
+static void blkfront_handler(evtchn_port_t port, struct pt_regs *regs,
+			     void *data)
+{
+	printf("%s [Port %d] - event received\n", __func__, port);
+}
+
 static int init_blkfront(unsigned int devid, struct blkfront_dev *dev)
 {
+	xenbus_transaction_t xbt;
+	char *err = NULL;
+	char *message = NULL;
+	struct blkif_sring *s;
+	int retry = 0;
+	char *msg = NULL;
+	char *c;
+	char nodename[32];
+	char path[ARRAY_SIZE(nodename) + strlen("/backend-id") + 1];
+
+	sprintf(nodename, "device/vbd/%d", devid);
+
+	memset(dev, 0, sizeof(*dev));
+	dev->nodename = strdup(nodename);
+	dev->devid = devid;
+
+	snprintf(path, sizeof(path), "%s/backend-id", nodename);
+	dev->dom = xenbus_read_integer(path);
+	evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn);
+
+	s = (struct blkif_sring *)memalign(PAGE_SIZE, PAGE_SIZE);
+	if (!s) {
+		printf("Failed to allocate shared ring\n");
+		goto error;
+	}
+
+	SHARED_RING_INIT(s);
+	FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE);
+
+	dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_pfn(s), 0);
+
+again:
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
+		printf("starting transaction\n");
+		free(err);
+	}
+
+	err = xenbus_printf(xbt, nodename, "ring-ref", "%u", dev->ring_ref);
+	if (err) {
+		message = "writing ring-ref";
+		goto abort_transaction;
+	}
+	err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
+	if (err) {
+		message = "writing event-channel";
+		goto abort_transaction;
+	}
+	err = xenbus_printf(xbt, nodename, "protocol", "%s",
+			    XEN_IO_PROTO_ABI_NATIVE);
+	if (err) {
+		message = "writing protocol";
+		goto abort_transaction;
+	}
+
+	snprintf(path, sizeof(path), "%s/state", nodename);
+	err = xenbus_switch_state(xbt, path, XenbusStateConnected);
+	if (err) {
+		message = "switching state";
+		goto abort_transaction;
+	}
+
+	err = xenbus_transaction_end(xbt, 0, &retry);
+	free(err);
+	if (retry) {
+		goto again;
+		printf("completing transaction\n");
+	}
+
+	goto done;
+
+abort_transaction:
+	free(err);
+	err = xenbus_transaction_end(xbt, 1, &retry);
+	printf("Abort transaction %s\n", message);
+	goto error;
+
+done:
+	snprintf(path, sizeof(path), "%s/backend", nodename);
+	msg = xenbus_read(XBT_NIL, path, &dev->backend);
+	if (msg) {
+		printf("Error %s when reading the backend path %s\n",
+		       msg, path);
+		goto error;
+	}
+
+	dev->handle = strtoul(strrchr(nodename, '/') + 1, NULL, 0);
+
+	{
+		XenbusState state;
+		char path[strlen(dev->backend) +
+			strlen("/feature-flush-cache") + 1];
+
+		snprintf(path, sizeof(path), "%s/mode", dev->backend);
+		msg = xenbus_read(XBT_NIL, path, &c);
+		if (msg) {
+			printf("Error %s when reading the mode\n", msg);
+			goto error;
+		}
+		if (*c == 'w')
+			dev->info.mode = O_RDWR;
+		else
+			dev->info.mode = O_RDONLY;
+		free(c);
+
+		snprintf(path, sizeof(path), "%s/state", dev->backend);
+
+		msg = NULL;
+		state = xenbus_read_integer(path);
+		while (!msg && state < XenbusStateConnected)
+			msg = xenbus_wait_for_state_change(path, &state);
+		if (msg || state != XenbusStateConnected) {
+			printf("backend not available, state=%d\n", state);
+			goto error;
+		}
+
+		snprintf(path, sizeof(path), "%s/info", dev->backend);
+		dev->info.info = xenbus_read_integer(path);
+
+		snprintf(path, sizeof(path), "%s/sectors", dev->backend);
+		/*
+		 * FIXME: read_integer returns an int, so disk size
+		 * limited to 1TB for now
+		 */
+		dev->info.sectors = xenbus_read_integer(path);
+
+		snprintf(path, sizeof(path), "%s/sector-size", dev->backend);
+		dev->info.sector_size = xenbus_read_integer(path);
+
+		snprintf(path, sizeof(path), "%s/feature-barrier",
+			 dev->backend);
+		dev->info.barrier = xenbus_read_integer(path);
+
+		snprintf(path, sizeof(path), "%s/feature-flush-cache",
+			 dev->backend);
+		dev->info.flush = xenbus_read_integer(path);
+	}
+	unmask_evtchn(dev->evtchn);
+
+	debug("%llu sectors of %u bytes\n",
+	      dev->info.sectors, dev->info.sector_size);
+
 	return 0;
+
+error:
+	free(msg);
+	free(err);
+	free_blkfront(dev);
+	return -ENODEV;
 }
 
 static void shutdown_blkfront(struct blkfront_dev *dev)
 {
+	char *err = NULL, *err2;
+	XenbusState state;
+
+	char path[strlen(dev->backend) + strlen("/state") + 1];
+	char nodename[strlen(dev->nodename) + strlen("/event-channel") + 1];
+
+	debug("Close " DRV_NAME ", device ID %d\n", dev->devid);
+
+	snprintf(path, sizeof(path), "%s/state", dev->backend);
+	snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
+
+	if ((err = xenbus_switch_state(XBT_NIL, nodename,
+				       XenbusStateClosing)) != NULL) {
+		printf("%s: error changing state to %d: %s\n", __func__,
+		       XenbusStateClosing, err);
+		goto close;
+	}
+
+	state = xenbus_read_integer(path);
+	while (!err && state < XenbusStateClosing)
+		err = xenbus_wait_for_state_change(path, &state);
+	free(err);
+
+	if ((err = xenbus_switch_state(XBT_NIL, nodename,
+				       XenbusStateClosed)) != NULL) {
+		printf("%s: error changing state to %d: %s\n", __func__,
+		       XenbusStateClosed, err);
+		goto close;
+	}
+
+	state = xenbus_read_integer(path);
+	while (state < XenbusStateClosed) {
+		err = xenbus_wait_for_state_change(path, &state);
+		free(err);
+	}
+
+	if ((err = xenbus_switch_state(XBT_NIL, nodename,
+				       XenbusStateInitialising)) != NULL) {
+		printf("%s: error changing state to %d: %s\n", __func__,
+		       XenbusStateInitialising, err);
+		goto close;
+	}
+
+	state = xenbus_read_integer(path);
+	while (!err &&
+	       (state < XenbusStateInitWait || state >= XenbusStateClosed))
+		err = xenbus_wait_for_state_change(path, &state);
+
+close:
+	free(err);
+
+	snprintf(nodename, sizeof(nodename), "%s/ring-ref", dev->nodename);
+	err2 = xenbus_rm(XBT_NIL, nodename);
+	free(err2);
+	snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
+	err2 = xenbus_rm(XBT_NIL, nodename);
+	free(err2);
+
+	if (!err)
+		free_blkfront(dev);
 }
 
 ulong pvblock_blk_read(struct udevice *udev, lbaint_t blknr, lbaint_t blkcnt,
@@ -73,6 +350,7 @@ static int pvblock_blk_probe(struct udevice *udev)
 {
 	struct blkfront_dev *blk_dev = dev_get_priv(udev);
 	struct blkfront_platdata *platdata = dev_get_platdata(udev);
+	struct blk_desc *desc = dev_get_uclass_platdata(udev);
 	int ret, devid;
 
 	devid = platdata->devid;
@@ -81,6 +359,11 @@ static int pvblock_blk_probe(struct udevice *udev)
 	ret = init_blkfront(devid, blk_dev);
 	if (ret < 0)
 		return ret;
+
+	desc->blksz = blk_dev->info.sector_size;
+	desc->lba = blk_dev->info.sectors;
+	desc->log2blksz = LOG2(blk_dev->info.sector_size);
+
 	return 0;
 }
 
-- 
2.17.1

  parent reply	other threads:[~2020-08-06  9:42 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-06  9:42 [RESEND PATCH v2 00/18] Add new board: Xen guest for ARM64 Anastasiia Lukianenko
2020-08-06  9:42 ` [RESEND PATCH v2 01/18] Add MIT License Anastasiia Lukianenko
2020-08-14 19:49   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 02/18] Kconfig: Introduce CONFIG_XEN Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 03/18] xen: Add essential and required interface headers Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 04/18] board: Introduce xenguest_arm64 board Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 05/18] xen: Port Xen hypervisor related code from mini-os Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 06/18] xen: Port Xen event channel driver " Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 07/18] serial: serial_xen: Add Xen PV serial driver Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 08/18] linux/compat.h: Add wait_event_timeout macro Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 09/18] lib: sscanf: add sscanf implementation Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-16  8:23   ` Andy Shevchenko
     [not found]     ` <999cf014-ac1b-51b6-0522-f75e5ac3a3ed@epam.com>
2020-08-17 12:12       ` Artem Mygaiev
2020-08-17 14:19         ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 10/18] xen: Port Xen bus driver from mini-os Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 11/18] xen: Port Xen grant table " Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 12/18] xen: pvblock: Add initial support for para-virtualized block driver Anastasiia Lukianenko
2020-08-14 19:50   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 13/18] xen: pvblock: Enumerate virtual block devices Anastasiia Lukianenko
2020-08-14 19:51   ` Tom Rini
2020-08-06  9:42 ` Anastasiia Lukianenko [this message]
2020-08-14 19:51   ` [RESEND PATCH v2 14/18] xen: pvblock: Read XenStore configuration and initialize Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 15/18] xen: pvblock: Implement front-back protocol and do IO Anastasiia Lukianenko
2020-08-14 19:51   ` Tom Rini
2020-08-06  9:42 ` [RESEND PATCH v2 16/18] xen: pvblock: Print found devices indices Anastasiia Lukianenko
2020-08-14 19:51   ` Tom Rini
2020-08-06  9:43 ` [RESEND PATCH v2 17/18] board: xen: De-initialize before jumping to Linux Anastasiia Lukianenko
2020-08-14 19:51   ` Tom Rini
2020-08-06  9:43 ` [RESEND PATCH v2 18/18] doc: xen: Add Xen guest ARM64 board documentation Anastasiia Lukianenko
2020-08-14 19:51   ` Tom Rini
2020-08-13  7:57 ` [RESEND PATCH v2 00/18] Add new board: Xen guest for ARM64 Oleksandr Andrushchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200806094301.4999-15-vicooodin@gmail.com \
    --to=vicooodin@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.