/**
* @file
* @section AUTHORS
*
* Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
*
* Authors:
* Rafal Wojtczuk <rafal@invisiblethingslab.com>
* Daniel De Graaf <dgdegra@tycho.nsa.gov>
*
* @section LICENSE
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* @section DESCRIPTION
*
* Originally borrowed from the Qubes OS Project, http://www.qubes-os.org,
* this code has been substantially rewritten to use the gntdev and gntalloc
* devices instead of raw MFNs and map_foreign_range.
*
* This is a library for inter-domain communication. A standard Xen ring
* buffer is used, with a datagram-based interface built on top. The grant
* reference and event channels are shared in XenStore under the path
* /local/domain/<srv-id>/data/vchan/<cli-id>/<port>/{ring-ref,event-channel}
*
* The ring.h macros define an asymmetric interface to a shared data structure
* that assumes all rings reside in a single contiguous memory space. This is
* not suitable for vchan because the interface to the ring is symmetric except
* for the setup. Unlike the producer-consumer rings defined in ring.h, the
* size of the rings used in vchan are determined at execution time instead of
* compile time, so the macros in ring.h cannot be used to access the rings.
*/
#include <xen/io/libxenvchan.h>
#include <xen/sys/evtchn.h>
#include <xenctrl.h>
struct libxenvchan_ring {
/* Pointer into the shared page. Offsets into buffer. */
struct ring_shared* shr;
/* ring data; may be its own shared page(s) depending on order */
void* buffer;
/**
* The size of the ring is (1 << order); offsets wrap around when they
* exceed this. This copy is required because we can't trust the order
* in the shared page to remain constant.
*/
int order;
};
/**
* struct libxenvchan: control structure passed to all library calls
*/
struct libxenvchan {
/* Mapping handle for shared ring page */
union {
xc_gntshr *gntshr; /* for server */
xc_gnttab *gnttab; /* for client */
};
/* Pointer to shared ring page */
struct vchan_interface *ring;
/* event channel interface */
xc_evtchn *event;
uint32_t event_port;
/* informative flags: are we acting as server? */
int