// SPDX-License-Identifier: GPL-2.0
/*
 * (C) 2006 - Cambridge University
 * (C) 2020 - EPAM Systems Inc.
 *
 * File: xenbus.c [1]
 * Author: Steven Smith (sos22@cam.ac.uk)
 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
 * Changes: John D. Ramsdell
 *
 * Date: Jun 2006, changes Aug 2006
 *
 * Description: Minimal implementation of xenbus
 *
 * [1] - http://xenbits.xen.org/gitweb/?p=mini-os.git;a=summary
 */

#include <log.h>

#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/xen/system.h>

#include <linux/bug.h>
#include <linux/compat.h>

#include <xen/events.h>
#include <xen/hvm.h>
#include <xen/xenbus.h>

#include <xen/interface/io/xs_wire.h>

#define map_frame_virt(v)	(v << PAGE_SHIFT)

#define SCNd16			"d"

/* Wait for reply time out, ms */
#define WAIT_XENBUS_TO_MS	5000
/* Polling time out, ms */
#define WAIT_XENBUS_POLL_TO_MS	1

static struct xenstore_domain_interface *xenstore_buf;

static char *errmsg(struct xsd_sockmsg *rep);

u32 xenbus_evtchn;

struct write_req {
	const void *data;
	unsigned int len;
};

static void memcpy_from_ring(const void *r, void *d, int off, int len)
{
	int c1, c2;
	const char *ring = r;
	char *dest = d;

	c1 = min(len, XENSTORE_RING_SIZE - off);
	c2 = len - c1;
	memcpy(dest, ring + off, c1);
	memcpy(dest + c1, ring, c2);
}

/**
 * xenbus_get_reply() - Receive reply from xenbus
 * @req_reply: reply message structure
 *
 * Wait for reply message event from the ring and copy received message
 * to input xsd_sockmsg structure. Repeat until full reply is
 * proceeded.
 *
 * Return: false - timeout
 *	   true - reply is received
 */
static bool xenbus_get_reply(struct xsd_sockmsg **req_reply)
{
	struct xsd_sockmsg msg;
	unsigned int prod = xenstore_buf->rsp_prod;

again:
	if (!wait_event_timeout(NULL, prod != xenstore_buf->rsp_prod,
				WAIT_XENBUS_TO_MS)) {
		printk("%s: wait_event timeout\n", __func__);
		return false;
	}

	prod = xenstore_buf->rsp_prod;
	if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
		goto again;

	rmb();
	memcpy_from_ring(xenstore_buf->rsp, &msg,
			 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
			 sizeof(msg));

	if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg) + msg.len)
		goto again;

	/* We do not support and expect any Xen bus wathes. */
	BUG_ON(msg.type == XS_WATCH_EVENT);

	*req_reply = malloc(sizeof(msg) + msg.len);
	memcpy_from_ring(xenstore_buf->rsp, *req_reply,
			 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
			 msg.len + sizeof(msg));
	mb();
	xenstore_buf->rsp_cons += msg.len + sizeof(msg);

	wmb();
	notify_remote_via_evtchn(xenbus_evtchn);
	return true;
}

char *xenbus_switch_state(xenbus_transaction_t xbt, const char *path,
			  XenbusState state)
{
	char *current_state;
	char *msg = NULL;
	char *msg2 = NULL;
	char value[2];
	XenbusState rs;
	int xbt_flag = 0;
	int retry = 0;

	do {
		if (xbt == XBT_NIL) {
			msg = xenbus_transaction_start(&xbt);
			if (msg)
				goto exit;
			xbt_flag = 1;
		}

		msg = xenbus_read(xbt, path, &current_state);
		if (msg)
			goto exit;

		rs = (XenbusState)(current_state[0] - '0');
		free(current_state);
		if (rs == state) {
			msg = NULL;
			goto exit;
		}

		snprintf(value, 2, "%d", state);
		msg = xenbus_write(xbt, path, value);

exit:
		if (xbt_flag) {
			msg2 = xenbus_transaction_end(xbt, 0, &retry);
			xbt = XBT_NIL;
		}
		if (msg == NULL && msg2 != NULL)
			msg = msg2;
		else
			free(msg2);
	} while (retry);

	return msg;
}

char *xenbus_wait_for_state_change(const char *path, XenbusState *state)
{
	for (;;) {
		char *res, *msg;
		XenbusState rs;

		msg = xenbus_read(XBT_NIL, path, &res);
		if (msg)
			return msg;

		rs = (XenbusState)(res[0] - 48);
		free(res);

		if (rs == *state) {
			wait_event_timeout(NULL, false, WAIT_XENBUS_POLL_TO_MS);
		} else {
			*state = rs;
			break;
		}
	}
	return NULL;
}

/* Send data to xenbus.  This can block.  All of the requests are seen
 * by xenbus as if sent atomically.  The header is added
 * automatically, using type %type, req_id %req_id, and trans_id
 * %trans_id.
 */
static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
		     const struct write_req *req, int nr_reqs)
{
	XENSTORE_RING_IDX prod;
	int r;
	int len = 0;
	const struct write_req *cur_req;
	int req_off;
	int total_off;
	int this_chunk;
	struct xsd_sockmsg m = {
		.type = type,
		.req_id = req_id,
		.tx_id = trans_id
	};
	struct write_req header_req = {
		&m,
		sizeof(m)
	};

	for (r = 0; r < nr_reqs; r++)
		len += req[r].len;
	m.len = len;
	len += sizeof(m);

	cur_req = &header_req;

	BUG_ON(len > XENSTORE_RING_SIZE);
	prod = xenstore_buf->req_prod;
	/* We are running synchronously, so it is a bug if we do not
	 * have enough room to send a message: please note that a message
	 * can occupy multiple slots in the ring buffer.
	 */
	BUG_ON(prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE);

	total_off = 0;
	req_off = 0;
	while (total_off < len) {
		this_chunk = min(cur_req->len - req_off,
				 XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
		memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
		       (char *)cur_req->data + req_off, this_chunk);
		prod += this_chunk;
		req_off += this_chunk;
		total_off += this_chunk;
		if (req_off == cur_req->len) {
			req_off = 0;
			if (cur_req == &header_req)
				cur_req = req;
			else
				cur_req++;
		}
	}

	BUG_ON(req_off != 0);
	BUG_ON(total_off != len);
	BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);

	/* Remote must see entire message before updating indexes */
	wmb();

	xenstore_buf->req_prod += len;

	/* Send evtchn to notify remote */
	notify_remote_via_evtchn(xenbus_evtchn);
}

/* Send a message to xenbus, in the same fashion as xb_write, and
 * block waiting for a reply.  The reply is malloced and should be
 * freed by the caller.
 */
struct xsd_sockmsg *xenbus_msg_reply(int type,
				     xenbus_transaction_t trans,
				     struct write_req *io,
				     int nr_reqs)
{
	struct xsd_sockmsg *rep;

	/* We do not use request identifier which is echoed in daemon's response. */
	xb_write(type, 0, trans, io, nr_reqs);
	/* Now wait for the message to arrive. */
	if (!xenbus_get_reply(&rep))
		return NULL;
	return rep;
}

static char *errmsg(struct xsd_sockmsg *rep)
{
	char *res;

	if (!rep) {
		char msg[] = "No reply";
		size_t len = strlen(msg) + 1;

		return memcpy(malloc(len), msg, len);
	}
	if (rep->type != XS_ERROR)
		return NULL;
	res = malloc(rep->len + 1);
	memcpy(res, rep + 1, rep->len);
	res[rep->len] = 0;
	free(rep);
	return res;
}

/* List the contents of a directory.  Returns a malloc()ed array of
 * pointers to malloc()ed strings.  The array is NULL terminated.  May
 * block.
 */
char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
{
	struct xsd_sockmsg *reply, *repmsg;
	struct write_req req[] = { { pre, strlen(pre) + 1 } };
	int nr_elems, x, i;
	char **res, *msg;

	repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(repmsg);
	if (msg) {
		*contents = NULL;
		return msg;
	}
	reply = repmsg + 1;
	for (x = nr_elems = 0; x < repmsg->len; x++)
		nr_elems += (((char *)reply)[x] == 0);
	res = malloc(sizeof(res[0]) * (nr_elems + 1));
	for (x = i = 0; i < nr_elems; i++) {
		int l = strlen((char *)reply + x);

		res[i] = malloc(l + 1);
		memcpy(res[i], (char *)reply + x, l + 1);
		x += l + 1;
	}
	res[i] = NULL;
	free(repmsg);
	*contents = res;
	return NULL;
}

char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
{
	struct write_req req[] = { {path, strlen(path) + 1} };
	struct xsd_sockmsg *rep;
	char *res, *msg;

	rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(rep);
	if (msg) {
		*value = NULL;
		return msg;
	}
	res = malloc(rep->len + 1);
	memcpy(res, rep + 1, rep->len);
	res[rep->len] = 0;
	free(rep);
	*value = res;
	return NULL;
}

char *xenbus_write(xenbus_transaction_t xbt, const char *path,
				   const char *value)
{
	struct write_req req[] = {
		{path, strlen(path) + 1},
		{value, strlen(value)},
	};
	struct xsd_sockmsg *rep;
	char *msg;

	rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(rep);
	if (msg)
		return msg;
	free(rep);
	return NULL;
}

char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
{
	struct write_req req[] = { {path, strlen(path) + 1} };
	struct xsd_sockmsg *rep;
	char *msg;

	rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(rep);
	if (msg)
		return msg;
	free(rep);
	return NULL;
}

char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
{
	struct write_req req[] = { {path, strlen(path) + 1} };
	struct xsd_sockmsg *rep;
	char *res, *msg;

	rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(rep);
	if (msg) {
		*value = NULL;
		return msg;
	}
	res = malloc(rep->len + 1);
	memcpy(res, rep + 1, rep->len);
	res[rep->len] = 0;
	free(rep);
	*value = res;
	return NULL;
}

#define PERM_MAX_SIZE 32
char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path,
		       domid_t dom, char perm)
{
	char value[PERM_MAX_SIZE];
	struct write_req req[] = {
		{path, strlen(path) + 1},
		{value, 0},
	};
	struct xsd_sockmsg *rep;
	char *msg;

	snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
	req[1].len = strlen(value) + 1;
	rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
	msg = errmsg(rep);
	if (msg)
		return msg;
	free(rep);
	return NULL;
}

char *xenbus_transaction_start(xenbus_transaction_t *xbt)
{
	/* Xenstored becomes angry if you send a length 0 message, so just
	 * shove a nul terminator on the end
	 */
	struct write_req req = { "", 1};
	struct xsd_sockmsg *rep;
	char *err;

	rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
	err = errmsg(rep);
	if (err)
		return err;
	sscanf((char *)(rep + 1), "%lu", xbt);
	free(rep);
	return NULL;
}

char *xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
{
	struct xsd_sockmsg *rep;
	struct write_req req;
	char *err;

	*retry = 0;

	req.data = abort ? "F" : "T";
	req.len = 2;
	rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
	err = errmsg(rep);
	if (err) {
		if (!strcmp(err, "EAGAIN")) {
			*retry = 1;
			free(err);
			return NULL;
		} else {
			return err;
		}
	}
	free(rep);
	return NULL;
}

int xenbus_read_integer(const char *path)
{
	char *res, *buf;
	int t;

	res = xenbus_read(XBT_NIL, path, &buf);
	if (res) {
		printk("Failed to read %s.\n", path);
		free(res);
		return -1;
	}
	sscanf(buf, "%d", &t);
	free(buf);
	return t;
}

int xenbus_read_uuid(const char *path, unsigned char uuid[16])
{
	char *res, *buf;

	res = xenbus_read(XBT_NIL, path, &buf);
	if (res) {
		printk("Failed to read %s.\n", path);
		free(res);
		return 0;
	}
	if (strlen(buf) != ((2 * 16) + 4) /* 16 hex bytes and 4 hyphens */
	    || sscanf(buf,
		      "%2hhx%2hhx%2hhx%2hhx-"
		      "%2hhx%2hhx-"
		      "%2hhx%2hhx-"
		      "%2hhx%2hhx-"
		      "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
		      uuid, uuid + 1, uuid + 2, uuid + 3,
		      uuid + 4, uuid + 5, uuid + 6, uuid + 7,
		      uuid + 8, uuid + 9, uuid + 10, uuid + 11,
		      uuid + 12, uuid + 13, uuid + 14, uuid + 15) != 16) {
		printk("Xenbus path %s value %s is not a uuid!\n", path, buf);
		free(buf);
		return 0;
	}
	free(buf);
	return 1;
}

char *xenbus_printf(xenbus_transaction_t xbt,
		    const char *node, const char *path,
		    const char *fmt, ...)
{
#define BUFFER_SIZE 256
	char fullpath[BUFFER_SIZE];
	char val[BUFFER_SIZE];
	va_list args;

	BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
	sprintf(fullpath, "%s/%s", node, path);
	va_start(args, fmt);
	vsprintf(val, fmt, args);
	va_end(args);
	return xenbus_write(xbt, fullpath, val);
}

domid_t xenbus_get_self_id(void)
{
	char *dom_id;
	domid_t ret;

	BUG_ON(xenbus_read(XBT_NIL, "domid", &dom_id));
	sscanf(dom_id, "%"SCNd16, &ret);

	return ret;
}

void init_xenbus(void)
{
	u64 v;

	debug("%s\n", __func__);
	if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v))
		BUG();
	xenbus_evtchn = v;

	if (hvm_get_parameter(HVM_PARAM_STORE_PFN, &v))
		BUG();
	xenstore_buf = (struct xenstore_domain_interface *)map_frame_virt(v);
}

void fini_xenbus(void)
{
	debug("%s\n", __func__);
}
