1 /****************************************************************************** 2 * xenbus_comms.c 3 * 4 * Low level code to talks to Xen Store: ringbuffer and event channel. 5 * 6 * Copyright (C) 2005 Rusty Russell, IBM Corporation 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 2 10 * as published by the Free Software Foundation; or, when distributed 11 * separately from the Linux kernel or incorporated into other 12 * software packages, subject to the following license: 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a copy 15 * of this source file (the "Software"), to deal in the Software without 16 * restriction, including without limitation the rights to use, copy, modify, 17 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 18 * and to permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 * IN THE SOFTWARE. 31 */ 32 33 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 34 35 #include <linux/wait.h> 36 #include <linux/interrupt.h> 37 #include <linux/sched.h> 38 #include <linux/err.h> 39 #include <xen/xenbus.h> 40 #include <asm/xen/hypervisor.h> 41 #include <xen/events.h> 42 #include <xen/page.h> 43 #include "xenbus_comms.h" 44 45 static int xenbus_irq; 46 47 static DECLARE_WORK(probe_work, xenbus_probe); 48 49 static DECLARE_WAIT_QUEUE_HEAD(xb_waitq); 50 51 static irqreturn_t wake_waiting(int irq, void *unused) 52 { 53 if (unlikely(xenstored_ready == 0)) { 54 xenstored_ready = 1; 55 schedule_work(&probe_work); 56 } 57 58 wake_up(&xb_waitq); 59 return IRQ_HANDLED; 60 } 61 62 static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) 63 { 64 return ((prod - cons) <= XENSTORE_RING_SIZE); 65 } 66 67 static void *get_output_chunk(XENSTORE_RING_IDX cons, 68 XENSTORE_RING_IDX prod, 69 char *buf, uint32_t *len) 70 { 71 *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod); 72 if ((XENSTORE_RING_SIZE - (prod - cons)) < *len) 73 *len = XENSTORE_RING_SIZE - (prod - cons); 74 return buf + MASK_XENSTORE_IDX(prod); 75 } 76 77 static const void *get_input_chunk(XENSTORE_RING_IDX cons, 78 XENSTORE_RING_IDX prod, 79 const char *buf, uint32_t *len) 80 { 81 *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); 82 if ((prod - cons) < *len) 83 *len = prod - cons; 84 return buf + MASK_XENSTORE_IDX(cons); 85 } 86 87 /** 88 * xb_write - low level write 89 * @data: buffer to send 90 * @len: length of buffer 91 * 92 * Returns 0 on success, error otherwise. 93 */ 94 int xb_write(const void *data, unsigned len) 95 { 96 struct xenstore_domain_interface *intf = xen_store_interface; 97 XENSTORE_RING_IDX cons, prod; 98 int rc; 99 100 while (len != 0) { 101 void *dst; 102 unsigned int avail; 103 104 rc = wait_event_interruptible( 105 xb_waitq, 106 (intf->req_prod - intf->req_cons) != 107 XENSTORE_RING_SIZE); 108 if (rc < 0) 109 return rc; 110 111 /* Read indexes, then verify. */ 112 cons = intf->req_cons; 113 prod = intf->req_prod; 114 if (!check_indexes(cons, prod)) { 115 intf->req_cons = intf->req_prod = 0; 116 return -EIO; 117 } 118 119 dst = get_output_chunk(cons, prod, intf->req, &avail); 120 if (avail == 0) 121 continue; 122 if (avail > len) 123 avail = len; 124 125 /* Must write data /after/ reading the consumer index. */ 126 mb(); 127 128 memcpy(dst, data, avail); 129 data += avail; 130 len -= avail; 131 132 /* Other side must not see new producer until data is there. */ 133 wmb(); 134 intf->req_prod += avail; 135 136 /* Implies mb(): other side will see the updated producer. */ 137 notify_remote_via_evtchn(xen_store_evtchn); 138 } 139 140 return 0; 141 } 142 143 int xb_data_to_read(void) 144 { 145 struct xenstore_domain_interface *intf = xen_store_interface; 146 return (intf->rsp_cons != intf->rsp_prod); 147 } 148 149 int xb_wait_for_data_to_read(void) 150 { 151 return wait_event_interruptible(xb_waitq, xb_data_to_read()); 152 } 153 154 int xb_read(void *data, unsigned len) 155 { 156 struct xenstore_domain_interface *intf = xen_store_interface; 157 XENSTORE_RING_IDX cons, prod; 158 int rc; 159 160 while (len != 0) { 161 unsigned int avail; 162 const char *src; 163 164 rc = xb_wait_for_data_to_read(); 165 if (rc < 0) 166 return rc; 167 168 /* Read indexes, then verify. */ 169 cons = intf->rsp_cons; 170 prod = intf->rsp_prod; 171 if (!check_indexes(cons, prod)) { 172 intf->rsp_cons = intf->rsp_prod = 0; 173 return -EIO; 174 } 175 176 src = get_input_chunk(cons, prod, intf->rsp, &avail); 177 if (avail == 0) 178 continue; 179 if (avail > len) 180 avail = len; 181 182 /* Must read data /after/ reading the producer index. */ 183 rmb(); 184 185 memcpy(data, src, avail); 186 data += avail; 187 len -= avail; 188 189 /* Other side must not see free space until we've copied out */ 190 mb(); 191 intf->rsp_cons += avail; 192 193 pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); 194 195 /* Implies mb(): other side will see the updated consumer. */ 196 notify_remote_via_evtchn(xen_store_evtchn); 197 } 198 199 return 0; 200 } 201 202 /** 203 * xb_init_comms - Set up interrupt handler off store event channel. 204 */ 205 int xb_init_comms(void) 206 { 207 struct xenstore_domain_interface *intf = xen_store_interface; 208 209 if (intf->req_prod != intf->req_cons) 210 pr_err("request ring is not quiescent (%08x:%08x)!\n", 211 intf->req_cons, intf->req_prod); 212 213 if (intf->rsp_prod != intf->rsp_cons) { 214 pr_warn("response ring is not quiescent (%08x:%08x): fixing up\n", 215 intf->rsp_cons, intf->rsp_prod); 216 /* breaks kdump */ 217 if (!reset_devices) 218 intf->rsp_cons = intf->rsp_prod; 219 } 220 221 if (xenbus_irq) { 222 /* Already have an irq; assume we're resuming */ 223 rebind_evtchn_irq(xen_store_evtchn, xenbus_irq); 224 } else { 225 int err; 226 err = bind_evtchn_to_irqhandler(xen_store_evtchn, wake_waiting, 227 0, "xenbus", &xb_waitq); 228 if (err < 0) { 229 pr_err("request irq failed %i\n", err); 230 return err; 231 } 232 233 xenbus_irq = err; 234 } 235 236 return 0; 237 } 238 239 void xb_deinit_comms(void) 240 { 241 unbind_from_irqhandler(xenbus_irq, &xb_waitq); 242 xenbus_irq = 0; 243 } 244