All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anastasiia Lukianenko <vicooodin@gmail.com>
To: u-boot@lists.denx.de
Subject: [PATCH 14/17] xen: pvblock: Read XenStore configuration and initialize
Date: Wed,  1 Jul 2020 19:29:56 +0300	[thread overview]
Message-ID: <20200701162959.9814-15-vicooodin@gmail.com> (raw)
In-Reply-To: <20200701162959.9814-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>
---
 drivers/xen/pvblock.c | 272 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 271 insertions(+), 1 deletion(-)

diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c
index 6ce0ae97c3..9ed18be633 100644
--- a/drivers/xen/pvblock.c
+++ b/drivers/xen/pvblock.c
@@ -1,6 +1,7 @@
 /*
  * SPDX-License-Identifier:	GPL-2.0+
  *
+ * (C) 2007-2008 Samuel Thibault.
  * (C) Copyright 2020 EPAM Systems Inc.
  */
 #include <blk.h>
@@ -10,26 +11,289 @@
 #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 {
-	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 == NULL && state < XenbusStateConnected)
+			msg = xenbus_wait_for_state_change(path, &state);
+		if (msg != NULL || 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 == NULL && 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 == NULL &&
+	       (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,
@@ -74,6 +338,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;
@@ -82,6 +347,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-07-01 16:29 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-01 16:29 [PATCH 00/17] Add new board: Xen guest for ARM64 Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 01/17] armv8: Fix SMCC and ARM_PSCI_FW dependencies Anastasiia Lukianenko
2020-07-02  1:14   ` Peng Fan
2020-07-03  9:57     ` Nastya Vicodin
2020-07-01 16:29 ` [PATCH 02/17] Kconfig: Introduce CONFIG_XEN Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-03 12:42     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 03/17] board: Introduce xenguest_arm64 board Anastasiia Lukianenko
2020-07-02  1:28   ` Peng Fan
2020-07-02  7:18     ` Oleksandr Andrushchenko
2020-07-02  7:26       ` Heinrich Schuchardt
2020-07-02  7:57         ` Oleksandr Andrushchenko
2020-07-01 16:29 ` [PATCH 04/17] xen: Add essential and required interface headers Anastasiia Lukianenko
2020-07-02  1:30   ` Peng Fan
2020-07-03 12:46     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 05/17] xen: Port Xen hypervizor related code from mini-os Anastasiia Lukianenko
2020-07-01 17:46   ` Julien Grall
2020-07-03 12:21     ` Anastasiia Lukianenko
2020-07-03 13:38       ` Julien Grall
2020-07-08  8:55         ` Anastasiia Lukianenko
2020-07-16 13:16     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 06/17] xen: Port Xen event channel driver " Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-03 12:34     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 07/17] serial: serial_xen: Add Xen PV serial driver Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-03 12:59     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 08/17] linux/compat.h: Add wait_event_timeout macro Anastasiia Lukianenko
2020-07-02  4:08   ` Heinrich Schuchardt
2020-07-03 13:02     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 09/17] lib: sscanf: add sscanf implementation Anastasiia Lukianenko
2020-07-02  4:04   ` Heinrich Schuchardt
2020-07-01 16:29 ` [PATCH 10/17] xen: Port Xen bus driver from mini-os Anastasiia Lukianenko
2020-07-02  4:43   ` Heinrich Schuchardt
2020-07-01 16:29 ` [PATCH 11/17] xen: Port Xen grant table " Anastasiia Lukianenko
2020-07-01 16:59   ` Julien Grall
2020-07-03 13:09     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 12/17] xen: pvblock: Add initial support for para-virtualized block driver Anastasiia Lukianenko
2020-07-02  4:17   ` Heinrich Schuchardt
2020-07-03 13:25     ` Anastasiia Lukianenko
2020-07-02  4:29   ` Heinrich Schuchardt
2020-07-02  5:30     ` Peng Fan
2020-07-03 14:14     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 13/17] xen: pvblock: Enumerate virtual block devices Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-01 16:29 ` Anastasiia Lukianenko [this message]
2020-07-03  3:50   ` [PATCH 14/17] xen: pvblock: Read XenStore configuration and initialize Simon Glass
2020-07-06  9:08     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 15/17] xen: pvblock: Implement front-back protocol and do IO Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-06  9:10     ` Anastasiia Lukianenko
2020-07-01 16:29 ` [PATCH 16/17] xen: pvblock: Print found devices indices Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-01 16:29 ` [PATCH 17/17] board: xen: De-initialize before jumping to Linux Anastasiia Lukianenko
2020-07-03  3:50   ` Simon Glass
2020-07-06  9:13     ` Anastasiia Lukianenko
2020-07-01 16:51 ` [PATCH 00/17] Add new board: Xen guest for ARM64 Anastasiia Lukianenko

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=20200701162959.9814-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.