1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) 2006 - Cambridge University
4  * (C) 2020 - EPAM Systems Inc.
5  *
6  * File: xenbus.c [1]
7  * Author: Steven Smith (sos22@cam.ac.uk)
8  * Changes: Grzegorz Milos (gm281@cam.ac.uk)
9  * Changes: John D. Ramsdell
10  *
11  * Date: Jun 2006, changes Aug 2006
12  *
13  * Description: Minimal implementation of xenbus
14  *
15  * [1] - http://xenbits.xen.org/gitweb/?p=mini-os.git;a=summary
16  */
17 
18 #include <common.h>
19 #include <log.h>
20 
21 #include <asm/armv8/mmu.h>
22 #include <asm/io.h>
23 #include <asm/xen/system.h>
24 
25 #include <linux/bug.h>
26 #include <linux/compat.h>
27 
28 #include <xen/events.h>
29 #include <xen/hvm.h>
30 #include <xen/xenbus.h>
31 
32 #include <xen/interface/io/xs_wire.h>
33 
34 #define map_frame_virt(v)	(v << PAGE_SHIFT)
35 
36 #define SCNd16			"d"
37 
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
42 
43 static struct xenstore_domain_interface *xenstore_buf;
44 
45 static char *errmsg(struct xsd_sockmsg *rep);
46 
47 u32 xenbus_evtchn;
48 
49 struct write_req {
50 	const void *data;
51 	unsigned int len;
52 };
53 
memcpy_from_ring(const void * r,void * d,int off,int len)54 static void memcpy_from_ring(const void *r, void *d, int off, int len)
55 {
56 	int c1, c2;
57 	const char *ring = r;
58 	char *dest = d;
59 
60 	c1 = min(len, XENSTORE_RING_SIZE - off);
61 	c2 = len - c1;
62 	memcpy(dest, ring + off, c1);
63 	memcpy(dest + c1, ring, c2);
64 }
65 
66 /**
67  * xenbus_get_reply() - Receive reply from xenbus
68  * @req_reply: reply message structure
69  *
70  * Wait for reply message event from the ring and copy received message
71  * to input xsd_sockmsg structure. Repeat until full reply is
72  * proceeded.
73  *
74  * Return: false - timeout
75  *	   true - reply is received
76  */
xenbus_get_reply(struct xsd_sockmsg ** req_reply)77 static bool xenbus_get_reply(struct xsd_sockmsg **req_reply)
78 {
79 	struct xsd_sockmsg msg;
80 	unsigned int prod = xenstore_buf->rsp_prod;
81 
82 again:
83 	if (!wait_event_timeout(NULL, prod != xenstore_buf->rsp_prod,
84 				WAIT_XENBUS_TO_MS)) {
85 		printk("%s: wait_event timeout\n", __func__);
86 		return false;
87 	}
88 
89 	prod = xenstore_buf->rsp_prod;
90 	if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
91 		goto again;
92 
93 	rmb();
94 	memcpy_from_ring(xenstore_buf->rsp, &msg,
95 			 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
96 			 sizeof(msg));
97 
98 	if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg) + msg.len)
99 		goto again;
100 
101 	/* We do not support and expect any Xen bus wathes. */
102 	BUG_ON(msg.type == XS_WATCH_EVENT);
103 
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));
108 	mb();
109 	xenstore_buf->rsp_cons += msg.len + sizeof(msg);
110 
111 	wmb();
112 	notify_remote_via_evtchn(xenbus_evtchn);
113 	return true;
114 }
115 
xenbus_switch_state(xenbus_transaction_t xbt,const char * path,XenbusState state)116 char *xenbus_switch_state(xenbus_transaction_t xbt, const char *path,
117 			  XenbusState state)
118 {
119 	char *current_state;
120 	char *msg = NULL;
121 	char *msg2 = NULL;
122 	char value[2];
123 	XenbusState rs;
124 	int xbt_flag = 0;
125 	int retry = 0;
126 
127 	do {
128 		if (xbt == XBT_NIL) {
129 			msg = xenbus_transaction_start(&xbt);
130 			if (msg)
131 				goto exit;
132 			xbt_flag = 1;
133 		}
134 
135 		msg = xenbus_read(xbt, path, &current_state);
136 		if (msg)
137 			goto exit;
138 
139 		rs = (XenbusState)(current_state[0] - '0');
140 		free(current_state);
141 		if (rs == state) {
142 			msg = NULL;
143 			goto exit;
144 		}
145 
146 		snprintf(value, 2, "%d", state);
147 		msg = xenbus_write(xbt, path, value);
148 
149 exit:
150 		if (xbt_flag) {
151 			msg2 = xenbus_transaction_end(xbt, 0, &retry);
152 			xbt = XBT_NIL;
153 		}
154 		if (msg == NULL && msg2 != NULL)
155 			msg = msg2;
156 		else
157 			free(msg2);
158 	} while (retry);
159 
160 	return msg;
161 }
162 
xenbus_wait_for_state_change(const char * path,XenbusState * state)163 char *xenbus_wait_for_state_change(const char *path, XenbusState *state)
164 {
165 	for (;;) {
166 		char *res, *msg;
167 		XenbusState rs;
168 
169 		msg = xenbus_read(XBT_NIL, path, &res);
170 		if (msg)
171 			return msg;
172 
173 		rs = (XenbusState)(res[0] - 48);
174 		free(res);
175 
176 		if (rs == *state) {
177 			wait_event_timeout(NULL, false, WAIT_XENBUS_POLL_TO_MS);
178 		} else {
179 			*state = rs;
180 			break;
181 		}
182 	}
183 	return NULL;
184 }
185 
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
189  * %trans_id.
190  */
xb_write(int type,int req_id,xenbus_transaction_t trans_id,const struct write_req * req,int nr_reqs)191 static void xb_write(int type, int req_id, xenbus_transaction_t trans_id,
192 		     const struct write_req *req, int nr_reqs)
193 {
194 	XENSTORE_RING_IDX prod;
195 	int r;
196 	int len = 0;
197 	const struct write_req *cur_req;
198 	int req_off;
199 	int total_off;
200 	int this_chunk;
201 	struct xsd_sockmsg m = {
202 		.type = type,
203 		.req_id = req_id,
204 		.tx_id = trans_id
205 	};
206 	struct write_req header_req = {
207 		&m,
208 		sizeof(m)
209 	};
210 
211 	for (r = 0; r < nr_reqs; r++)
212 		len += req[r].len;
213 	m.len = len;
214 	len += sizeof(m);
215 
216 	cur_req = &header_req;
217 
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.
223 	 */
224 	BUG_ON(prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE);
225 
226 	total_off = 0;
227 	req_off = 0;
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);
233 		prod += this_chunk;
234 		req_off += this_chunk;
235 		total_off += this_chunk;
236 		if (req_off == cur_req->len) {
237 			req_off = 0;
238 			if (cur_req == &header_req)
239 				cur_req = req;
240 			else
241 				cur_req++;
242 		}
243 	}
244 
245 	BUG_ON(req_off != 0);
246 	BUG_ON(total_off != len);
247 	BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
248 
249 	/* Remote must see entire message before updating indexes */
250 	wmb();
251 
252 	xenstore_buf->req_prod += len;
253 
254 	/* Send evtchn to notify remote */
255 	notify_remote_via_evtchn(xenbus_evtchn);
256 }
257 
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.
261  */
xenbus_msg_reply(int type,xenbus_transaction_t trans,struct write_req * io,int nr_reqs)262 struct xsd_sockmsg *xenbus_msg_reply(int type,
263 				     xenbus_transaction_t trans,
264 				     struct write_req *io,
265 				     int nr_reqs)
266 {
267 	struct xsd_sockmsg *rep;
268 
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))
273 		return NULL;
274 	return rep;
275 }
276 
errmsg(struct xsd_sockmsg * rep)277 static char *errmsg(struct xsd_sockmsg *rep)
278 {
279 	char *res;
280 
281 	if (!rep) {
282 		char msg[] = "No reply";
283 		size_t len = strlen(msg) + 1;
284 
285 		return memcpy(malloc(len), msg, len);
286 	}
287 	if (rep->type != XS_ERROR)
288 		return NULL;
289 	res = malloc(rep->len + 1);
290 	memcpy(res, rep + 1, rep->len);
291 	res[rep->len] = 0;
292 	free(rep);
293 	return res;
294 }
295 
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
298  * block.
299  */
xenbus_ls(xenbus_transaction_t xbt,const char * pre,char *** contents)300 char *xenbus_ls(xenbus_transaction_t xbt, const char *pre, char ***contents)
301 {
302 	struct xsd_sockmsg *reply, *repmsg;
303 	struct write_req req[] = { { pre, strlen(pre) + 1 } };
304 	int nr_elems, x, i;
305 	char **res, *msg;
306 
307 	repmsg = xenbus_msg_reply(XS_DIRECTORY, xbt, req, ARRAY_SIZE(req));
308 	msg = errmsg(repmsg);
309 	if (msg) {
310 		*contents = NULL;
311 		return msg;
312 	}
313 	reply = repmsg + 1;
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);
319 
320 		res[i] = malloc(l + 1);
321 		memcpy(res[i], (char *)reply + x, l + 1);
322 		x += l + 1;
323 	}
324 	res[i] = NULL;
325 	free(repmsg);
326 	*contents = res;
327 	return NULL;
328 }
329 
xenbus_read(xenbus_transaction_t xbt,const char * path,char ** value)330 char *xenbus_read(xenbus_transaction_t xbt, const char *path, char **value)
331 {
332 	struct write_req req[] = { {path, strlen(path) + 1} };
333 	struct xsd_sockmsg *rep;
334 	char *res, *msg;
335 
336 	rep = xenbus_msg_reply(XS_READ, xbt, req, ARRAY_SIZE(req));
337 	msg = errmsg(rep);
338 	if (msg) {
339 		*value = NULL;
340 		return msg;
341 	}
342 	res = malloc(rep->len + 1);
343 	memcpy(res, rep + 1, rep->len);
344 	res[rep->len] = 0;
345 	free(rep);
346 	*value = res;
347 	return NULL;
348 }
349 
xenbus_write(xenbus_transaction_t xbt,const char * path,const char * value)350 char *xenbus_write(xenbus_transaction_t xbt, const char *path,
351 				   const char *value)
352 {
353 	struct write_req req[] = {
354 		{path, strlen(path) + 1},
355 		{value, strlen(value)},
356 	};
357 	struct xsd_sockmsg *rep;
358 	char *msg;
359 
360 	rep = xenbus_msg_reply(XS_WRITE, xbt, req, ARRAY_SIZE(req));
361 	msg = errmsg(rep);
362 	if (msg)
363 		return msg;
364 	free(rep);
365 	return NULL;
366 }
367 
xenbus_rm(xenbus_transaction_t xbt,const char * path)368 char *xenbus_rm(xenbus_transaction_t xbt, const char *path)
369 {
370 	struct write_req req[] = { {path, strlen(path) + 1} };
371 	struct xsd_sockmsg *rep;
372 	char *msg;
373 
374 	rep = xenbus_msg_reply(XS_RM, xbt, req, ARRAY_SIZE(req));
375 	msg = errmsg(rep);
376 	if (msg)
377 		return msg;
378 	free(rep);
379 	return NULL;
380 }
381 
xenbus_get_perms(xenbus_transaction_t xbt,const char * path,char ** value)382 char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value)
383 {
384 	struct write_req req[] = { {path, strlen(path) + 1} };
385 	struct xsd_sockmsg *rep;
386 	char *res, *msg;
387 
388 	rep = xenbus_msg_reply(XS_GET_PERMS, xbt, req, ARRAY_SIZE(req));
389 	msg = errmsg(rep);
390 	if (msg) {
391 		*value = NULL;
392 		return msg;
393 	}
394 	res = malloc(rep->len + 1);
395 	memcpy(res, rep + 1, rep->len);
396 	res[rep->len] = 0;
397 	free(rep);
398 	*value = res;
399 	return NULL;
400 }
401 
402 #define PERM_MAX_SIZE 32
xenbus_set_perms(xenbus_transaction_t xbt,const char * path,domid_t dom,char perm)403 char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path,
404 		       domid_t dom, char perm)
405 {
406 	char value[PERM_MAX_SIZE];
407 	struct write_req req[] = {
408 		{path, strlen(path) + 1},
409 		{value, 0},
410 	};
411 	struct xsd_sockmsg *rep;
412 	char *msg;
413 
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));
417 	msg = errmsg(rep);
418 	if (msg)
419 		return msg;
420 	free(rep);
421 	return NULL;
422 }
423 
xenbus_transaction_start(xenbus_transaction_t * xbt)424 char *xenbus_transaction_start(xenbus_transaction_t *xbt)
425 {
426 	/* Xenstored becomes angry if you send a length 0 message, so just
427 	 * shove a nul terminator on the end
428 	 */
429 	struct write_req req = { "", 1};
430 	struct xsd_sockmsg *rep;
431 	char *err;
432 
433 	rep = xenbus_msg_reply(XS_TRANSACTION_START, 0, &req, 1);
434 	err = errmsg(rep);
435 	if (err)
436 		return err;
437 	sscanf((char *)(rep + 1), "%lu", xbt);
438 	free(rep);
439 	return NULL;
440 }
441 
xenbus_transaction_end(xenbus_transaction_t t,int abort,int * retry)442 char *xenbus_transaction_end(xenbus_transaction_t t, int abort, int *retry)
443 {
444 	struct xsd_sockmsg *rep;
445 	struct write_req req;
446 	char *err;
447 
448 	*retry = 0;
449 
450 	req.data = abort ? "F" : "T";
451 	req.len = 2;
452 	rep = xenbus_msg_reply(XS_TRANSACTION_END, t, &req, 1);
453 	err = errmsg(rep);
454 	if (err) {
455 		if (!strcmp(err, "EAGAIN")) {
456 			*retry = 1;
457 			free(err);
458 			return NULL;
459 		} else {
460 			return err;
461 		}
462 	}
463 	free(rep);
464 	return NULL;
465 }
466 
xenbus_read_integer(const char * path)467 int xenbus_read_integer(const char *path)
468 {
469 	char *res, *buf;
470 	int t;
471 
472 	res = xenbus_read(XBT_NIL, path, &buf);
473 	if (res) {
474 		printk("Failed to read %s.\n", path);
475 		free(res);
476 		return -1;
477 	}
478 	sscanf(buf, "%d", &t);
479 	free(buf);
480 	return t;
481 }
482 
xenbus_read_uuid(const char * path,unsigned char uuid[16])483 int xenbus_read_uuid(const char *path, unsigned char uuid[16])
484 {
485 	char *res, *buf;
486 
487 	res = xenbus_read(XBT_NIL, path, &buf);
488 	if (res) {
489 		printk("Failed to read %s.\n", path);
490 		free(res);
491 		return 0;
492 	}
493 	if (strlen(buf) != ((2 * 16) + 4) /* 16 hex bytes and 4 hyphens */
494 	    || sscanf(buf,
495 		      "%2hhx%2hhx%2hhx%2hhx-"
496 		      "%2hhx%2hhx-"
497 		      "%2hhx%2hhx-"
498 		      "%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);
505 		free(buf);
506 		return 0;
507 	}
508 	free(buf);
509 	return 1;
510 }
511 
xenbus_printf(xenbus_transaction_t xbt,const char * node,const char * path,const char * fmt,...)512 char *xenbus_printf(xenbus_transaction_t xbt,
513 		    const char *node, const char *path,
514 		    const char *fmt, ...)
515 {
516 #define BUFFER_SIZE 256
517 	char fullpath[BUFFER_SIZE];
518 	char val[BUFFER_SIZE];
519 	va_list args;
520 
521 	BUG_ON(strlen(node) + strlen(path) + 1 >= BUFFER_SIZE);
522 	sprintf(fullpath, "%s/%s", node, path);
523 	va_start(args, fmt);
524 	vsprintf(val, fmt, args);
525 	va_end(args);
526 	return xenbus_write(xbt, fullpath, val);
527 }
528 
xenbus_get_self_id(void)529 domid_t xenbus_get_self_id(void)
530 {
531 	char *dom_id;
532 	domid_t ret;
533 
534 	BUG_ON(xenbus_read(XBT_NIL, "domid", &dom_id));
535 	sscanf(dom_id, "%"SCNd16, &ret);
536 
537 	return ret;
538 }
539 
init_xenbus(void)540 void init_xenbus(void)
541 {
542 	u64 v;
543 
544 	debug("%s\n", __func__);
545 	if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v))
546 		BUG();
547 	xenbus_evtchn = v;
548 
549 	if (hvm_get_parameter(HVM_PARAM_STORE_PFN, &v))
550 		BUG();
551 	xenstore_buf = (struct xenstore_domain_interface *)map_frame_virt(v);
552 }
553 
fini_xenbus(void)554 void fini_xenbus(void)
555 {
556 	debug("%s\n", __func__);
557 }
558