1 // SPDX-License-Identifier: GPL-2.0
3 * (C) 2006 - Cambridge University
4 * (C) 2020 - EPAM Systems Inc.
9 * Changes: John D. Ramsdell
11 * Date: Jun 2006, changes Aug 2006
13 * Description: Minimal implementation of xenbus
15 * [1] - http://xenbits.xen.org/gitweb/?p=mini-os.git;a=summary
21 #include <asm/armv8/mmu.h>
23 #include <asm/xen/system.h>
25 #include <linux/bug.h>
26 #include <linux/compat.h>
28 #include <xen/events.h>
30 #include <xen/xenbus.h>
32 #include <xen/interface/io/xs_wire.h>
34 #define map_frame_virt(v) (v << PAGE_SHIFT)
38 /* Wait for reply time out, ms */
39 #define WAIT_XENBUS_TO_MS 5000
40 /* Polling time out, ms */
41 #define WAIT_XENBUS_POLL_TO_MS 1
43 static struct xenstore_domain_interface *xenstore_buf;
45 static char *errmsg(struct xsd_sockmsg *rep);
54 static void memcpy_from_ring(const void *r, void *d, int off, int len)
60 c1 = min(len, XENSTORE_RING_SIZE - off);
62 memcpy(dest, ring + off, c1);
63 memcpy(dest + c1, ring, c2);
67 * xenbus_get_reply() - Receive reply from xenbus
68 * @req_reply: reply message structure
70 * Wait for reply message event from the ring and copy received message
71 * to input xsd_sockmsg structure. Repeat until full reply is
74 * Return: false - timeout
75 * true - reply is received
77 static bool xenbus_get_reply(struct xsd_sockmsg **req_reply)
79 struct xsd_sockmsg msg;
80 unsigned int prod = xenstore_buf->rsp_prod;
83 if (!wait_event_timeout(NULL, prod != xenstore_buf->rsp_prod,
85 printk("%s: wait_event timeout\n", __func__);
89 prod = xenstore_buf->rsp_prod;
90 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
94 memcpy_from_ring(xenstore_buf->rsp, &msg,
95 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
98 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg) + msg.len)
101 /* We do not support and expect any Xen bus wathes. */
102 BUG_ON(msg.type == XS_WATCH_EVENT);
104 *req_reply = malloc(sizeof(msg) + msg.len);
105 memcpy_from_ring(xenstore_buf->rsp, *req_reply,
106 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
107 msg.len + sizeof(msg));
109 xenstore_buf->rsp_cons += msg.len + sizeof(msg);
112 notify_remote_via_evtchn(xenbus_evtchn);
116 char *xenbus_switch_state(xenbus_transaction_t xbt, const char *path,
128 if (xbt == XBT_NIL) {
129 msg = xenbus_transaction_start(&xbt);
135 msg = xenbus_read(xbt, path, ¤t_state);
139 rs = (XenbusState)(current_state[0] - '0');
146 snprintf(value, 2, "%d", state);
147 msg = xenbus_write(xbt, path, value);
151 msg2 = xenbus_transaction_end(xbt, 0, &retry);
154 if (msg == NULL && msg2 != NULL)
163 char *xenbus_wait_for_state_change(const char *path, XenbusState *state)
169 msg = xenbus_read(XBT_NIL, path, &res);
173 rs = (XenbusState)(res[0] - 48);
177 wait_event_timeout(NULL, false, WAIT_XENBUS_POLL_TO_MS);
186 /* Send data to xenbus. This can block. All of the requests are seen
187 * by xenbus as if sent atomically. The header is added
188 * automatically, using type %type, req_id %req_id, and trans_id
191 static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
192 const struct write_req *req, int nr_reqs)
194 XENSTORE_RING_IDX prod;
197 const struct write_req *cur_req;
201 struct xsd_sockmsg m = {
206 struct write_req header_req = {
211 for (r = 0; r < nr_reqs; r++)
216 cur_req = &header_req;
218 BUG_ON(len > XENSTORE_RING_SIZE);
219 prod = xenstore_buf->req_prod;
220 /* We are running synchronously, so it is a bug if we do not
221 * have enough room to send a message: please note that a message
222 * can occupy multiple slots in the ring buffer.
224 BUG_ON(prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE);
228 while (total_off < len) {
229 this_chunk = min(cur_req->len - req_off,
230 XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
231 memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
232 (char *)cur_req->data + req_off, this_chunk);
234 req_off += this_chunk;
235 total_off += this_chunk;
236 if (req_off == cur_req->len) {
238 if (cur_req == &header_req)
245 BUG_ON(req_off != 0);
246 BUG_ON(total_off != len);
247 BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
249 /* Remote must see entire message before updating indexes */
252 xenstore_buf->req_prod += len;
254 /* Send evtchn to notify remote */
255 notify_remote_via_evtchn(xenbus_evtchn);
258 /* Send a message to xenbus, in the same fashion as xb_write, and
259 * block waiting for a reply. The reply is malloced and should be
260 * freed by the caller.
262 struct xsd_sockmsg *xenbus_msg_reply(int type,
263 xenbus_transaction_t trans,
264 struct write_req *io,
267 struct xsd_sockmsg *rep;
269 /* We do not use request identifier which is echoed in daemon's response. */
270 xb_write(type, 0, trans, io, nr_reqs);
271 /* Now wait for the message to arrive. */
272 if (!xenbus_get_reply(&rep))
277 static char *errmsg(struct xsd_sockmsg *rep)
282 char msg[] = "No reply";
283 size_t len = strlen(msg) + 1;
285 return memcpy(malloc(len), msg, len);
287 if (rep->type != XS_ERROR)
289 res = malloc(rep->len + 1);
290 memcpy(res, rep + 1, rep->len);
296 /* List the contents of a directory. Returns a malloc()ed array of
297 * pointers to malloc()ed strings. The array is NULL terminated. May
300 char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
302 struct xsd_sockmsg *reply, *repmsg;
303 struct write_req req[] = { { pre, strlen(pre) + 1 } };
307 repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
308 msg = errmsg(repmsg);
314 for (x = nr_elems = 0; x < repmsg->len; x++)
315 nr_elems += (((char *)reply)[x] == 0);
316 res = malloc(sizeof(res[0]) * (nr_elems + 1));
317 for (x = i = 0; i < nr_elems; i++) {
318 int l = strlen((char *)reply + x);
320 res[i] = malloc(l + 1);
321 memcpy(res[i], (char *)reply + x, l + 1);
330 char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
332 struct write_req req[] = { {path, strlen(path) + 1} };
333 struct xsd_sockmsg *rep;
336 rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
342 res = malloc(rep->len + 1);
343 memcpy(res, rep + 1, rep->len);
350 char *xenbus_write(xenbus_transaction_t xbt, const char *path,
353 struct write_req req[] = {
354 {path, strlen(path) + 1},
355 {value, strlen(value)},
357 struct xsd_sockmsg *rep;
360 rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
368 char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
370 struct write_req req[] = { {path, strlen(path) + 1} };
371 struct xsd_sockmsg *rep;
374 rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
382 char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
384 struct write_req req[] = { {path, strlen(path) + 1} };
385 struct xsd_sockmsg *rep;
388 rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
394 res = malloc(rep->len + 1);
395 memcpy(res, rep + 1, rep->len);
402 #define PERM_MAX_SIZE 32
403 char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path,
404 domid_t dom, char perm)
406 char value[PERM_MAX_SIZE];
407 struct write_req req[] = {
408 {path, strlen(path) + 1},
411 struct xsd_sockmsg *rep;
414 snprintf(value, PERM_MAX_SIZE, "%c%hu", perm, dom);
415 req[1].len = strlen(value) + 1;
416 rep = xenbus_msg_reply(XS_SET_PERMS, xbt, req, ARRAY_SIZE(req));
424 char *xenbus_transaction_start(xenbus_transaction_t *xbt)
426 /* Xenstored becomes angry if you send a length 0 message, so just
427 * shove a nul terminator on the end
429 struct write_req req = { "", 1};
430 struct xsd_sockmsg *rep;
433 rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
437 sscanf((char *)(rep + 1), "%lu", xbt);
442 char *xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
444 struct xsd_sockmsg *rep;
445 struct write_req req;
450 req.data = abort ? "F" : "T";
452 rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
455 if (!strcmp(err, "EAGAIN")) {
467 int xenbus_read_integer(const char *path)
472 res = xenbus_read(XBT_NIL, path, &buf);
474 printk("Failed to read %s.\n", path);
478 sscanf(buf, "%d", &t);
483 int xenbus_read_uuid(const char *path, unsigned char uuid[16])
487 res = xenbus_read(XBT_NIL, path, &buf);
489 printk("Failed to read %s.\n", path);
493 if (strlen(buf) != ((2 * 16) + 4) /* 16 hex bytes and 4 hyphens */
495 "%2hhx%2hhx%2hhx%2hhx-"
499 "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
500 uuid, uuid + 1, uuid + 2, uuid + 3,
501 uuid + 4, uuid + 5, uuid + 6, uuid + 7,
502 uuid + 8, uuid + 9, uuid + 10, uuid + 11,
503 uuid + 12, uuid + 13, uuid + 14, uuid + 15) != 16) {
504 printk("Xenbus path %s value %s is not a uuid!\n", path, buf);
512 char *xenbus_printf(xenbus_transaction_t xbt,
513 const char *node, const char *path,
514 const char *fmt, ...)
516 #define BUFFER_SIZE 256
517 char fullpath[BUFFER_SIZE];
518 char val[BUFFER_SIZE];
521 BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
522 sprintf(fullpath, "%s/%s", node, path);
524 vsprintf(val, fmt, args);
526 return xenbus_write(xbt, fullpath, val);
529 domid_t xenbus_get_self_id(void)
534 BUG_ON(xenbus_read(XBT_NIL, "domid", &dom_id));
535 sscanf(dom_id, "%"SCNd16, &ret);
540 void init_xenbus(void)
544 debug("%s\n", __func__);
545 if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v))
549 if (hvm_get_parameter(HVM_PARAM_STORE_PFN, &v))
551 xenstore_buf = (struct xenstore_domain_interface *)map_frame_virt(v);
554 void fini_xenbus(void)
556 debug("%s\n", __func__);