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