Merge branch '2021-01-15-assorted-improvements'
[platform/kernel/u-boot.git] / drivers / xen / xenbus.c
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
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  */
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
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
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  */
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  */
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
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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
554 void fini_xenbus(void)
555 {
556         debug("%s\n", __func__);
557 }