1 /** 2 * @file 3 * @section AUTHORS 4 * 5 * Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com> 6 * 7 * Authors: 8 * Rafal Wojtczuk <rafal@invisiblethingslab.com> 9 * Daniel De Graaf <dgdegra@tycho.nsa.gov> 10 * 11 * @section LICENSE 12 * 13 * This library is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU Lesser General Public 15 * License as published by the Free Software Foundation; either 16 * version 2.1 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; If not, see <http://www.gnu.org/licenses/>. 25 * 26 * @section DESCRIPTION 27 * 28 * Originally borrowed from the Qubes OS Project, http://www.qubes-os.org, 29 * this code has been substantially rewritten to use the gntdev and gntalloc 30 * devices instead of raw MFNs and map_foreign_range. 31 * 32 * This is a library for inter-domain communication. A standard Xen ring 33 * buffer is used, with a datagram-based interface built on top. The grant 34 * reference and event channels are shared in XenStore under the path 35 * /local/domain/<srv-id>/data/vchan/<cli-id>/<port>/{ring-ref,event-channel} 36 * 37 * The ring.h macros define an asymmetric interface to a shared data structure 38 * that assumes all rings reside in a single contiguous memory space. This is 39 * not suitable for vchan because the interface to the ring is symmetric except 40 * for the setup. Unlike the producer-consumer rings defined in ring.h, the 41 * size of the rings used in vchan are determined at execution time instead of 42 * compile time, so the macros in ring.h cannot be used to access the rings. 43 */ 44 45 #include <xen/io/libxenvchan.h> 46 #include <xen/xen.h> 47 #include <xen/sys/evtchn.h> 48 #include <xenevtchn.h> 49 #include <xengnttab.h> 50 51 /* Callers who don't care don't need to #include <xentoollog.h> */ 52 struct xentoollog_logger; 53 54 struct libxenvchan_ring { 55 /* Pointer into the shared page. Offsets into buffer. */ 56 struct ring_shared* shr; 57 /* ring data; may be its own shared page(s) depending on order */ 58 void* buffer; 59 /** 60 * The size of the ring is (1 << order); offsets wrap around when they 61 * exceed this. This copy is required because we can't trust the order 62 * in the shared page to remain constant. 63 */ 64 int order; 65 }; 66 67 /** 68 * struct libxenvchan: control structure passed to all library calls 69 */ 70 struct libxenvchan { 71 /* Mapping handle for shared ring page */ 72 union { 73 xengntshr_handle *gntshr; /* for server */ 74 xengnttab_handle *gnttab; /* for client */ 75 }; 76 /* Pointer to shared ring page */ 77 struct vchan_interface *ring; 78 /* event channel interface */ 79 xenevtchn_handle *event; 80 uint32_t event_port; 81 /* informative flags: are we acting as server? */ 82 unsigned int is_server:1; 83 /* true if server remains active when client closes (allows reconnection) */ 84 unsigned int server_persist:1; 85 /* true if operations should block instead of returning 0 */ 86 unsigned int blocking:1; 87 /* communication rings */ 88 struct libxenvchan_ring read, write; 89 /** 90 * Base xenstore path for storing ring/event data used by the server 91 * during cleanup. 92 * */ 93 char *xs_path; 94 }; 95 96 /** 97 * Set up a vchan, including granting pages 98 * @param logger Logger for libxc errors 99 * @param domain The peer domain that will be connecting 100 * @param xs_path Base xenstore path for storing ring/event data 101 * @param send_min The minimum size (in bytes) of the send ring (left) 102 * @param recv_min The minimum size (in bytes) of the receive ring (right) 103 * @return The structure, or NULL in case of an error 104 */ 105 struct libxenvchan *libxenvchan_server_init(struct xentoollog_logger *logger, 106 int domain, const char* xs_path, 107 size_t read_min, size_t write_min); 108 /** 109 * Connect to an existing vchan. Note: you can reconnect to an existing vchan 110 * safely, however no locking is performed, so you must prevent multiple clients 111 * from connecting to a single server. 112 * 113 * @param logger Logger for libxc errors 114 * @param domain The peer domain to connect to 115 * @param xs_path Base xenstore path for storing ring/event data 116 * @return The structure, or NULL in case of an error 117 */ 118 struct libxenvchan *libxenvchan_client_init(struct xentoollog_logger *logger, 119 int domain, const char* xs_path); 120 /** 121 * Close a vchan. This deallocates the vchan and attempts to free its 122 * resources. The other side is notified of the close, but can still read any 123 * data pending prior to the close. 124 */ 125 void libxenvchan_close(struct libxenvchan *ctrl); 126 127 /** 128 * Packet-based receive: always reads exactly $size bytes. 129 * @param ctrl The vchan control structure 130 * @param data Buffer for data that was read 131 * @param size Size of the buffer and amount of data to read 132 * @return -1 on error, 0 if nonblocking and insufficient data is available, or $size 133 */ 134 int libxenvchan_recv(struct libxenvchan *ctrl, void *data, size_t size); 135 /** 136 * Stream-based receive: reads as much data as possible. 137 * @param ctrl The vchan control structure 138 * @param data Buffer for data that was read 139 * @param size Size of the buffer 140 * @return -1 on error, otherwise the amount of data read (which may be zero if 141 * the vchan is nonblocking) 142 */ 143 int libxenvchan_read(struct libxenvchan *ctrl, void *data, size_t size); 144 /** 145 * Packet-based send: send entire buffer if possible 146 * @param ctrl The vchan control structure 147 * @param data Buffer for data to send 148 * @param size Size of the buffer and amount of data to send 149 * @return -1 on error, 0 if nonblocking and insufficient space is available, or $size 150 */ 151 int libxenvchan_send(struct libxenvchan *ctrl, const void *data, size_t size); 152 /** 153 * Stream-based send: send as much data as possible. 154 * @param ctrl The vchan control structure 155 * @param data Buffer for data to send 156 * @param size Size of the buffer 157 * @return -1 on error, otherwise the amount of data sent (which may be zero if 158 * the vchan is nonblocking) 159 */ 160 int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size); 161 /** 162 * Waits for reads or writes to unblock, or for a close 163 */ 164 int libxenvchan_wait(struct libxenvchan *ctrl); 165 /** 166 * Returns the event file descriptor for this vchan. When this FD is readable, 167 * libxenvchan_wait() will not block, and the state of the vchan has changed since 168 * the last invocation of libxenvchan_wait(). 169 */ 170 int libxenvchan_fd_for_select(struct libxenvchan *ctrl); 171 /** 172 * Query the state of the vchan shared page: 173 * return 0 when one side has called libxenvchan_close() or crashed 174 * return 1 when both sides are open 175 * return 2 [server only] when no client has yet connected 176 */ 177 int libxenvchan_is_open(struct libxenvchan* ctrl); 178 /** Amount of data ready to read, in bytes */ 179 int libxenvchan_data_ready(struct libxenvchan *ctrl); 180 /** Amount of data it is possible to send without blocking */ 181 int libxenvchan_buffer_space(struct libxenvchan *ctrl); 182