Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / interface / xen / xenstore.c
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdint.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <ipxe/io.h>
28 #include <ipxe/nap.h>
29 #include <ipxe/malloc.h>
30 #include <ipxe/xen.h>
31 #include <ipxe/xenevent.h>
32 #include <ipxe/xenstore.h>
33
34 /*
35  * xs_wire.h attempts to define a static error table xsd_errors, which
36  * interacts badly with the dynamically generated error numbers used
37  * by iPXE.  Prevent this table from being constructed by including
38  * errno.h only after including xs_wire.h.
39  *
40  */
41 #include <xen/io/xs_wire.h>
42 #include <errno.h>
43
44 /** @file
45  *
46  * XenStore interface
47  *
48  */
49
50 /** Request identifier */
51 static uint32_t xenstore_req_id;
52
53 /**
54  * Send XenStore request raw data
55  *
56  * @v xen               Xen hypervisor
57  * @v data              Data buffer
58  * @v len               Length of data
59  */
60 static void xenstore_send ( struct xen_hypervisor *xen, const void *data,
61                             size_t len ) {
62         struct xenstore_domain_interface *intf = xen->store.intf;
63         XENSTORE_RING_IDX prod = readl ( &intf->req_prod );
64         XENSTORE_RING_IDX cons;
65         XENSTORE_RING_IDX idx;
66         const char *bytes = data;
67         size_t offset = 0;
68         size_t fill;
69
70         DBGCP ( intf, "XENSTORE raw request:\n" );
71         DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len );
72
73         /* Write one byte at a time */
74         while ( offset < len ) {
75
76                 /* Wait for space to become available */
77                 while ( 1 ) {
78                         cons = readl ( &intf->req_cons );
79                         fill = ( prod - cons );
80                         if ( fill < XENSTORE_RING_SIZE )
81                                 break;
82                         DBGC2 ( xen, "." );
83                         cpu_nap();
84                         rmb();
85                 }
86
87                 /* Write byte */
88                 idx = MASK_XENSTORE_IDX ( prod++ );
89                 writeb ( bytes[offset++], &intf->req[idx] );
90         }
91
92         /* Update producer counter */
93         wmb();
94         writel ( prod, &intf->req_prod );
95         wmb();
96 }
97
98 /**
99  * Send XenStore request string (excluding terminating NUL)
100  *
101  * @v xen               Xen hypervisor
102  * @v string            String
103  */
104 static void xenstore_send_string ( struct xen_hypervisor *xen,
105                                    const char *string ) {
106
107         xenstore_send ( xen, string, strlen ( string ) );
108 }
109
110 /**
111  * Receive XenStore response raw data
112  *
113  * @v xen               Xen hypervisor
114  * @v data              Data buffer, or NULL to discard data
115  * @v len               Length of data
116  */
117 static void xenstore_recv ( struct xen_hypervisor *xen, void *data,
118                             size_t len ) {
119         struct xenstore_domain_interface *intf = xen->store.intf;
120         XENSTORE_RING_IDX cons = readl ( &intf->rsp_cons );
121         XENSTORE_RING_IDX prod;
122         XENSTORE_RING_IDX idx;
123         char *bytes = data;
124         size_t offset = 0;
125         size_t fill;
126
127         DBGCP ( intf, "XENSTORE raw response:\n" );
128
129         /* Read one byte at a time */
130         while ( offset < len ) {
131
132                 /* Wait for data to be ready */
133                 while ( 1 ) {
134                         prod = readl ( &intf->rsp_prod );
135                         fill = ( prod - cons );
136                         if ( fill > 0 )
137                                 break;
138                         DBGC2 ( xen, "." );
139                         cpu_nap();
140                         rmb();
141                 }
142
143                 /* Read byte */
144                 idx = MASK_XENSTORE_IDX ( cons++ );
145                 if ( data )
146                         bytes[offset++] = readb ( &intf->rsp[idx] );
147         }
148         if ( data )
149                 DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len );
150
151         /* Update consumer counter */
152         writel ( cons, &intf->rsp_cons );
153         wmb();
154 }
155
156 /**
157  * Send XenStore request
158  *
159  * @v xen               Xen hypervisor
160  * @v type              Message type
161  * @v req_id            Request ID
162  * @v value             Value, or NULL to omit
163  * @v key               Key path components
164  * @ret rc              Return status code
165  */
166 static int xenstore_request ( struct xen_hypervisor *xen,
167                               enum xsd_sockmsg_type type, uint32_t req_id,
168                               const char *value, va_list key ) {
169         struct xsd_sockmsg msg;
170         struct evtchn_send event;
171         const char *string;
172         va_list tmp;
173         int xenrc;
174         int rc;
175
176         /* Construct message header */
177         msg.type = type;
178         msg.req_id = req_id;
179         msg.tx_id = 0;
180         msg.len = 0;
181         DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );
182
183         /* Calculate total length */
184         va_copy ( tmp, key );
185         while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
186                 DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
187                 msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
188         }
189         va_end ( tmp );
190         if ( value ) {
191                 DBGC2 ( xen, " = \"%s\"", value );
192                 msg.len += strlen ( value );
193         }
194         DBGC2 ( xen, "\n" );
195
196         /* Send message */
197         xenstore_send ( xen, &msg, sizeof ( msg ) );
198         string = va_arg ( key, const char * );
199         assert ( string != NULL );
200         xenstore_send_string ( xen, string );
201         while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
202                 xenstore_send_string ( xen, "/" );
203                 xenstore_send_string ( xen, string );
204         }
205         xenstore_send ( xen, "", 1 ); /* Separating NUL */
206         if ( value )
207                 xenstore_send_string ( xen, value );
208
209         /* Notify the back end */
210         event.port = xen->store.port;
211         if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
212                 rc = -EXEN ( xenrc );
213                 DBGC ( xen, "XENSTORE could not notify back end: %s\n",
214                        strerror ( rc ) );
215                 return rc;
216         }
217
218         return 0;
219 }
220
221 /**
222  * Receive XenStore response
223  *
224  * @v xen               Xen hypervisor
225  * @v req_id            Request ID
226  * @v value             Value to fill in
227  * @v len               Length to fill in
228  * @ret rc              Return status code
229  *
230  * The caller is responsible for eventually calling free() on the
231  * returned value.  Note that the value may comprise multiple
232  * NUL-terminated strings concatenated together.  A terminating NUL
233  * will always be appended to the returned value.
234  */
235 static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
236                                char **value, size_t *len ) {
237         struct xsd_sockmsg msg;
238         char *string;
239         int rc;
240
241         /* Receive message header */
242         xenstore_recv ( xen, &msg, sizeof ( msg ) );
243         *len = msg.len;
244
245         /* Allocate space for response */
246         *value = zalloc ( msg.len + 1 /* terminating NUL */ );
247
248         /* Receive data.  Do this even if allocation failed, or if the
249          * request ID was incorrect, to avoid leaving data in the
250          * ring.
251          */
252         xenstore_recv ( xen, *value, msg.len );
253
254         /* Validate request ID */
255         if ( msg.req_id != req_id ) {
256                 DBGC ( xen, "XENSTORE response ID mismatch (got %d, expected "
257                        "%d)\n", msg.req_id, req_id );
258                 rc = -EPROTO;
259                 goto err_req_id;
260         }
261
262         /* Check for allocation failure */
263         if ( ! *value ) {
264                 DBGC ( xen, "XENSTORE could not allocate %d bytes for "
265                        "response\n", msg.len );
266                 rc = -ENOMEM;
267                 goto err_alloc;
268         }
269
270         /* Check for explicit errors */
271         if ( msg.type == XS_ERROR ) {
272                 DBGC ( xen, "XENSTORE response error \"%s\"\n", *value );
273                 rc = -EIO;
274                 goto err_explicit;
275         }
276
277         DBGC2 ( xen, "XENSTORE response ID %d\n", req_id );
278         if ( DBG_EXTRA ) {
279                 for ( string = *value ; string < ( *value + msg.len ) ;
280                       string += ( strlen ( string ) + 1 /* NUL */ ) ) {
281                         DBGC2 ( xen, " - \"%s\"\n", string );
282                 }
283         }
284         return 0;
285
286  err_explicit:
287  err_alloc:
288  err_req_id:
289         free ( *value );
290         *value = NULL;
291         return rc;
292 }
293
294 /**
295  * Issue a XenStore message
296  *
297  * @v xen               Xen hypervisor
298  * @v type              Message type
299  * @v response          Response value to fill in, or NULL to discard
300  * @v len               Response length to fill in, or NULL to ignore
301  * @v request           Request value, or NULL to omit
302  * @v key               Key path components
303  * @ret rc              Return status code
304  */
305 static int xenstore_message ( struct xen_hypervisor *xen,
306                               enum xsd_sockmsg_type type, char **response,
307                               size_t *len, const char *request, va_list key ) {
308         char *response_value;
309         size_t response_len;
310         int rc;
311
312         /* Send request */
313         if ( ( rc = xenstore_request ( xen, type, ++xenstore_req_id,
314                                        request, key ) ) != 0 )
315                 return rc;
316
317         /* Receive response */
318         if ( ( rc = xenstore_response ( xen, xenstore_req_id, &response_value,
319                                         &response_len ) ) != 0 )
320                 return rc;
321
322         /* Return response, if applicable */
323         if ( response ) {
324                 *response = response_value;
325         } else {
326                 free ( response_value );
327         }
328         if ( len )
329                 *len = response_len;
330
331         return 0;
332 }
333
334 /**
335  * Read XenStore value
336  *
337  * @v xen               Xen hypervisor
338  * @v value             Value to fill in
339  * @v key               Key path components
340  * @ret rc              Return status code
341  *
342  * On a successful return, the caller is responsible for calling
343  * free() on the returned value.
344  */
345 static int xenstore_vread ( struct xen_hypervisor *xen, char **value,
346                             va_list key ) {
347
348         return xenstore_message ( xen, XS_READ, value, NULL, NULL, key );
349 }
350
351 /**
352  * Read XenStore value
353  *
354  * @v xen               Xen hypervisor
355  * @v value             Value to fill in
356  * @v ...               Key path components
357  * @ret rc              Return status code
358  *
359  * On a successful return, the caller is responsible for calling
360  * free() on the returned value.
361  */
362 __attribute__ (( sentinel )) int
363 xenstore_read ( struct xen_hypervisor *xen, char **value, ... ) {
364         va_list key;
365         int rc;
366
367         va_start ( key, value );
368         rc = xenstore_vread ( xen, value, key );
369         va_end ( key );
370         return rc;
371 }
372
373 /**
374  * Read XenStore numeric value
375  *
376  * @v xen               Xen hypervisor
377  * @v num               Numeric value to fill in
378  * @v ...               Key path components
379  * @ret rc              Return status code
380  */
381 __attribute__ (( sentinel )) int
382 xenstore_read_num ( struct xen_hypervisor *xen, unsigned long *num, ... ) {
383         va_list key;
384         char *value;
385         char *endp;
386         int rc;
387
388         /* Try to read text value */
389         va_start ( key, num );
390         rc = xenstore_vread ( xen, &value, key );
391         va_end ( key );
392         if ( rc != 0 )
393                 goto err_read;
394
395         /* Try to parse as numeric value */
396         *num = strtoul ( value, &endp, 10 );
397         if ( ( *value == '\0' ) || ( *endp != '\0' ) ) {
398                 DBGC ( xen, "XENSTORE found invalid numeric value \"%s\"\n",
399                        value );
400                 rc = -EINVAL;
401                 goto err_strtoul;
402         }
403
404  err_strtoul:
405         free ( value );
406  err_read:
407         return rc;
408 }
409
410 /**
411  * Write XenStore value
412  *
413  * @v xen               Xen hypervisor
414  * @v value             Value
415  * @v key               Key path components
416  * @ret rc              Return status code
417  */
418 static int xenstore_vwrite ( struct xen_hypervisor *xen, const char *value,
419                              va_list key ) {
420
421         return xenstore_message ( xen, XS_WRITE, NULL, NULL, value, key );
422 }
423
424 /**
425  * Write XenStore value
426  *
427  * @v xen               Xen hypervisor
428  * @v value             Value
429  * @v ...               Key path components
430  * @ret rc              Return status code
431  */
432 __attribute__ (( sentinel )) int
433 xenstore_write ( struct xen_hypervisor *xen, const char *value, ... ) {
434         va_list key;
435         int rc;
436
437         va_start ( key, value );
438         rc = xenstore_vwrite ( xen, value, key );
439         va_end ( key );
440         return rc;
441 }
442
443 /**
444  * Write XenStore numeric value
445  *
446  * @v xen               Xen hypervisor
447  * @v num               Numeric value
448  * @v ...               Key path components
449  * @ret rc              Return status code
450  */
451 __attribute__ (( sentinel )) int
452 xenstore_write_num ( struct xen_hypervisor *xen, unsigned long num, ... ) {
453         char value[ 21 /* "18446744073709551615" + NUL */ ];
454         va_list key;
455         int rc;
456
457         /* Construct value */
458         snprintf ( value, sizeof ( value ), "%ld", num );
459
460         /* Write value */
461         va_start ( key, num );
462         rc = xenstore_vwrite ( xen, value, key );
463         va_end ( key );
464         return rc;
465 }
466
467 /**
468  * Delete XenStore value
469  *
470  * @v xen               Xen hypervisor
471  * @v ...               Key path components
472  * @ret rc              Return status code
473  */
474 __attribute__ (( sentinel )) int
475 xenstore_rm ( struct xen_hypervisor *xen, ... ) {
476         va_list key;
477         int rc;
478
479         va_start ( key, xen );
480         rc = xenstore_message ( xen, XS_RM, NULL, NULL, NULL, key );
481         va_end ( key );
482         return rc;
483 }
484
485 /**
486  * Read XenStore directory
487  *
488  * @v xen               Xen hypervisor
489  * @v children          Child key names to fill in
490  * @v len               Length of child key names to fill in
491  * @v ...               Key path components
492  * @ret rc              Return status code
493  */
494 __attribute__ (( sentinel )) int
495 xenstore_directory ( struct xen_hypervisor *xen, char **children, size_t *len,
496                      ... ) {
497         va_list key;
498         int rc;
499
500         va_start ( key, len );
501         rc = xenstore_message ( xen, XS_DIRECTORY, children, len, NULL, key );
502         va_end ( key );
503         return rc;
504 }
505
506 /**
507  * Dump XenStore directory contents (for debugging)
508  *
509  * @v xen               Xen hypervisor
510  * @v key               Key
511  */
512 void xenstore_dump ( struct xen_hypervisor *xen, const char *key ) {
513         char *value;
514         char *children;
515         char *child;
516         char *child_key;
517         size_t len;
518         int rc;
519
520         /* Try to dump current key as a value */
521         if ( ( rc = xenstore_read ( xen, &value, key, NULL ) ) == 0 ) {
522                 DBGC ( xen, "%s = \"%s\"\n", key, value );
523                 free ( value );
524         }
525
526         /* Try to recurse into each child in turn */
527         if ( ( rc = xenstore_directory ( xen, &children, &len, key,
528                                          NULL ) ) == 0 ) {
529                 for ( child = children ; child < ( children + len ) ;
530                       child += ( strlen ( child ) + 1 /* NUL */ ) ) {
531
532                         /* Construct child key */
533                         asprintf ( &child_key, "%s/%s", key, child );
534                         if ( ! child_key ) {
535                                 DBGC ( xen, "XENSTORE could not allocate child "
536                                        "key \"%s/%s\"\n", key, child );
537                                 rc = -ENOMEM;
538                                 break;
539                         }
540
541                         /* Recurse into child key, continuing on error */
542                         xenstore_dump ( xen, child_key );
543                         free ( child_key );
544                 }
545                 free ( children );
546         }
547 }