/******************************************************************************
 * xenbus_comms.c
 *
 * Low level code to talks to Xen Store: ringbuffer and event channel.
 *
 * Copyright (C) 2005 Rusty Russell, IBM Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation; or, when distributed
 * separately from the Linux kernel or incorporated into other
 * software packages, subject to the following license:
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this source file (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/sched.h>
#include <linux/err.h>
#include <xen/xenbus.h>
#include <asm/xen/hypervisor.h>
#include <xen/events.h>
#include <xen/page.h>
#include "xenbus.h"

/* A list of replies. Currently only one will ever be outstanding. */
LIST_HEAD(xs_reply_list);

/* A list of write requests. */
LIST_HEAD(xb_write_list);
DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
DEFINE_MUTEX(xb_write_mutex);

/* Protect xenbus reader thread against save/restore. */
DEFINE_MUTEX(xs_response_mutex);

static int xenbus_irq;
static struct task_struct *xenbus_task;

static DECLARE_WORK(probe_work, xenbus_probe);


static irqreturn_t wake_waiting(int irq, void *unused)
{
	if (unlikely(xenstored_ready == 0)) {
		xenstored_ready = 1;
		schedule_work(&probe_work);
	}

	wake_up(&xb_waitq);
	return IRQ_HANDLED;
}

static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
{
	return ((prod - cons) <= XENSTORE_RING_SIZE);
}

static void *get_output_chunk(XENSTORE_RING_IDX cons,
			      XENSTORE_RING_IDX prod,
			      char *buf, uint32_t *len)
{
	*len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod);
	if ((XENSTORE_RING_SIZE - (prod - cons)) < *len)
		*len = XENSTORE_RING_SIZE - (prod - cons);
	return buf + MASK_XENSTORE_IDX(prod);
}

static const void *get_input_chunk(XENSTORE_RING_IDX cons,
				   XENSTORE_RING_IDX prod,
				   const char *buf, uint32_t *len)
{
	*len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
	if ((prod - cons) < *len)
		*len = prod - cons;
	return buf + MASK_XENSTORE_IDX(cons);
}

static int xb_data_to_write(void)
{
	struct xenstore_domain_interface *intf = xen_store_interface;

	return (intf->req_prod - intf->req_cons) != XENSTORE_RING_SIZE &&
		!list_empty(&xb_write_list);
}

/**
 * xb_write - low level write
 * @data: buffer to send
 * @len: length of buffer
 *
 * Returns number of bytes written or -err.
 */
static int xb_write(const void *data, unsigned int len)
{
	struct xenstore_domain_interface *intf = xen_store_interface;
	XENSTORE_RING_IDX cons, prod;
	unsigned int bytes = 0;

	while (len != 0) {
		void *dst;
		unsigned int avail;

		/* Read indexes, then verify. */
		cons = intf->req_cons;
		prod = intf->req_prod;
		if (!check_indexes(cons, prod)) {
			intf->req_cons = intf->req_prod = 0;
			return -EIO;
		}
		if (!xb_data_to_write())
			return bytes;

		/* Must write data /after/ reading the consumer index. */
		virt_mb();

		dst = get_output_chunk(cons, prod, intf->req, &avail);
		if (avail == 0)
			continue;
		if (avail > len)
			avail = len;

		memcpy(dst, data, avail);
		data += avail;
		len -= avail;
		bytes += avail;

		/* Other side must not see new producer until data is there. */
		virt_wmb();
		intf->req_prod += avail;

		/* Implies mb(): other side will see the updated producer. */
		if (prod <= intf->req_cons)
			notify_remote_via_evtchn(xen_store_evtchn);
	}

	return bytes;
}

static int xb_data_to_read(void)
{
	struct xenstore_domain_interface *intf = xen_store_interface;
	return (intf->rsp_cons != intf->rsp_prod);
}

static int xb_read(void *data, unsigned int len)
{
	struct xenstore_domain_interface *intf = xen_store_interface;
	XENSTORE_RING_IDX cons, prod;
	unsigned int bytes = 0;

	while (len != 0) {
		unsigned int avail;
		const char *src;

		/* Read indexes, then verify. */
		cons = intf->rsp_cons;
		prod = intf->rsp_prod;
		if (cons == prod)
			return bytes;

		if (!check_indexes(cons, prod)) {
			intf->rsp_cons = intf->rsp_prod = 0;
			return -EIO;
		}

		src = get_input_chunk(cons, prod, intf->rsp, &avail);
		if (avail == 0)
			continue;
		if (avail > len)
			avail = len;

		/* Must read data /after/ reading the producer index. */
		virt_rmb();

		memcpy(data, src, avail);
		data += avail;
		len -= avail;
		bytes += avail;

		/* Other side must not see free space until we've copied out */
		virt_mb();
		intf->rsp_cons += avail;

		/* Implies mb(): other side will see the updated consumer. */
		if (intf->rsp_prod - cons >= XENSTORE_RING_SIZE)
			notify_remote_via_evtchn(xen_store_evtchn);
	}

	return bytes;
}

static int process_msg(void)
{
	static struct {
		struct xsd_sockmsg msg;
		char *body;
		union {
			void *alloc;
			struct xs_watch_event *watch;
		};
		bool in_msg;
		bool in_hdr;
		unsigned int read;
	} state;
	struct xb_req_data *req;
	int err;
	unsigned int len;

	if (!state.in_msg) {
		state.in_msg = true;
		state.in_hdr = true;
		state.read = 0;

		/*
		 * We must disallow save/restore while reading a message.
		 * A partial read across s/r leaves us out of sync with
		 * xenstored.
		 * xs_response_mutex is locked as long as we are processing one
		 * message. state.in_msg will be true as long as we are holding
		 * the lock here.
		 */
		mutex_lock(&xs_response_mutex);

		if (!xb_data_to_read()) {
			/* We raced with save/restore: pending data 'gone'. */
			mutex_unlock(&xs_response_mutex);
			state.in_msg = false;
			return 0;
		}
	}

	if (state.in_hdr) {
		if (state.read != sizeof(state.msg)) {
			err = xb_read((void *)&state.msg + state.read,
				      sizeof(state.msg) - state.read);
			if (err < 0)
				goto out;
			state.read += err;
			if (state.read != sizeof(state.msg))
				return 0;
			if (state.msg.len > XENSTORE_PAYLOAD_MAX) {
				err = -EINVAL;
				goto out;
			}
		}

		len = state.msg.len + 1;
		if (state.msg.type == XS_WATCH_EVENT)
			len += sizeof(*state.watch);

		state.alloc = kmalloc(len, GFP_NOIO | __GFP_HIGH);
		if (!state.alloc)
			return -ENOMEM;

		if (state.msg.type == XS_WATCH_EVENT)
			state.body = state.watch->body;
		else
			state.body = state.alloc;
		state.in_hdr = false;
		state.read = 0;
	}

	err = xb_read(state.body + state.read, state.msg.len - state.read);
	if (err < 0)
		goto out;

	state.read += err;
	if (state.read != state.msg.len)
		return 0;

	state.body[state.msg.len] = '\0';

	if (state.msg.type == XS_WATCH_EVENT) {
		state.watch->len = state.msg.len;
		err = xs_watch_msg(state.watch);
	} else {
		err = -ENOENT;
		mutex_lock(&xb_write_mutex);
		list_for_each_entry(req, &xs_reply_list, list) {
			if (req->msg.req_id == state.msg.req_id) {
				list_del(&req->list);
				err = 0;
				break;
			}
		}
		mutex_unlock(&xb_write_mutex);
		if (err)
			goto out;

		if (req->state == xb_req_state_wait_reply) {
			req->msg.type = state.msg.type;
			req->msg.len = state.msg.len;
			req->body = state.body;
			req->state = xb_req_state_got_reply;
			req->cb(req);
		} else
			kfree(req);
	}

	mutex_unlock(&xs_response_mutex);

	state.in_msg = false;
	state.alloc = NULL;
	return err;

 out:
	mutex_unlock(&xs_response_mutex);
	state.in_msg = false;
	kfree(state.alloc);
	state.alloc = NULL;
	return err;
}

static int process_writes(void)
{
	static struct {
		struct xb_req_data *req;
		int idx;
		unsigned int written;
	} state;
	void *base;
	unsigned int len;
	int err = 0;

	if (!xb_data_to_write())
		return 0;

	mutex_lock(&xb_write_mutex);

	if (!state.req) {
		state.req = list_first_entry(&xb_write_list,
					     struct xb_req_data, list);
		state.idx = -1;
		state.written = 0;
	}

	if (state.req->state == xb_req_state_aborted)
		goto out_err;

	while (state.idx < state.req->num_vecs) {
		if (state.idx < 0) {
			base = &state.req->msg;
			len = sizeof(state.req->msg);
		} else {
			base = state.req->vec[state.idx].iov_base;
			len = state.req->vec[state.idx].iov_len;
		}
		err = xb_write(base + state.written, len - state.written);
		if (err < 0)
			goto out_err;
		state.written += err;
		if (state.written != len)
			goto out;

		state.idx++;
		state.written = 0;
	}

	list_del(&state.req->list);
	state.req->state = xb_req_state_wait_reply;
	list_add_tail(&state.req->list, &xs_reply_list);
	state.req = NULL;

 out:
	mutex_unlock(&xb_write_mutex);

	return 0;

 out_err:
	state.req->msg.type = XS_ERROR;
	state.req->err = err;
	list_del(&state.req->list);
	if (state.req->state == xb_req_state_aborted)
		kfree(state.req);
	else {
		state.req->state = xb_req_state_got_reply;
		wake_up(&state.req->wq);
	}

	mutex_unlock(&xb_write_mutex);

	state.req = NULL;

	return err;
}

static int xb_thread_work(void)
{
	return xb_data_to_read() || xb_data_to_write();
}

static int xenbus_thread(void *unused)
{
	int err;

	while (!kthread_should_stop()) {
		if (wait_event_interruptible(xb_waitq, xb_thread_work()))
			continue;

		err = process_msg();
		if (err == -ENOMEM)
			schedule();
		else if (err)
			pr_warn_ratelimited("error %d while reading message\n",
					    err);

		err = process_writes();
		if (err)
			pr_warn_ratelimited("error %d while writing message\n",
					    err);
	}

	xenbus_task = NULL;
	return 0;
}

/**
 * xb_init_comms - Set up interrupt handler off store event channel.
 */
int xb_init_comms(void)
{
	struct xenstore_domain_interface *intf = xen_store_interface;

	if (intf->req_prod != intf->req_cons)
		pr_err("request ring is not quiescent (%08x:%08x)!\n",
		       intf->req_cons, intf->req_prod);

	if (intf->rsp_prod != intf->rsp_cons) {
		pr_warn("response ring is not quiescent (%08x:%08x): fixing up\n",
			intf->rsp_cons, intf->rsp_prod);
		/* breaks kdump */
		if (!reset_devices)
			intf->rsp_cons = intf->rsp_prod;
	}

	if (xenbus_irq) {
		/* Already have an irq; assume we're resuming */
		rebind_evtchn_irq(xen_store_evtchn, xenbus_irq);
	} else {
		int err;

		err = bind_evtchn_to_irqhandler(xen_store_evtchn, wake_waiting,
						0, "xenbus", &xb_waitq);
		if (err < 0) {
			pr_err("request irq failed %i\n", err);
			return err;
		}

		xenbus_irq = err;

		if (!xenbus_task) {
			xenbus_task = kthread_run(xenbus_thread, NULL,
						  "xenbus");
			if (IS_ERR(xenbus_task))
				return PTR_ERR(xenbus_task);
		}
	}

	return 0;
}

void xb_deinit_comms(void)
{
	unbind_from_irqhandler(xenbus_irq, &xb_waitq);
	xenbus_irq = 0;
}
