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