These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / hw / xen / xen_backend.c
1 /*
2  *  xen backend driver infrastructure
3  *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; under version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, see <http://www.gnu.org/licenses/>.
16  *
17  *  Contributions after 2012-01-13 are licensed under the terms of the
18  *  GNU GPL, version 2 or (at your option) any later version.
19  */
20
21 /*
22  * TODO: add some xenbus / xenstore concepts overview here.
23  */
24
25 #include "qemu/osdep.h"
26 #include <sys/mman.h>
27 #include <sys/signal.h>
28
29 #include "hw/hw.h"
30 #include "sysemu/char.h"
31 #include "qemu/log.h"
32 #include "hw/xen/xen_backend.h"
33
34 #include <xen/grant_table.h>
35
36 /* ------------------------------------------------------------- */
37
38 /* public */
39 xc_interface *xen_xc = NULL;
40 xenforeignmemory_handle *xen_fmem = NULL;
41 struct xs_handle *xenstore = NULL;
42 const char *xen_protocol;
43
44 /* private */
45 static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
46 static int debug = 0;
47
48 /* ------------------------------------------------------------- */
49
50 int xenstore_write_str(const char *base, const char *node, const char *val)
51 {
52     char abspath[XEN_BUFSIZE];
53
54     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
55     if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
56         return -1;
57     }
58     return 0;
59 }
60
61 char *xenstore_read_str(const char *base, const char *node)
62 {
63     char abspath[XEN_BUFSIZE];
64     unsigned int len;
65     char *str, *ret = NULL;
66
67     snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
68     str = xs_read(xenstore, 0, abspath, &len);
69     if (str != NULL) {
70         /* move to qemu-allocated memory to make sure
71          * callers can savely g_free() stuff. */
72         ret = g_strdup(str);
73         free(str);
74     }
75     return ret;
76 }
77
78 int xenstore_write_int(const char *base, const char *node, int ival)
79 {
80     char val[12];
81
82     snprintf(val, sizeof(val), "%d", ival);
83     return xenstore_write_str(base, node, val);
84 }
85
86 int xenstore_write_int64(const char *base, const char *node, int64_t ival)
87 {
88     char val[21];
89
90     snprintf(val, sizeof(val), "%"PRId64, ival);
91     return xenstore_write_str(base, node, val);
92 }
93
94 int xenstore_read_int(const char *base, const char *node, int *ival)
95 {
96     char *val;
97     int rc = -1;
98
99     val = xenstore_read_str(base, node);
100     if (val && 1 == sscanf(val, "%d", ival)) {
101         rc = 0;
102     }
103     g_free(val);
104     return rc;
105 }
106
107 int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
108 {
109     char *val;
110     int rc = -1;
111
112     val = xenstore_read_str(base, node);
113     if (val && 1 == sscanf(val, "%"SCNu64, uval)) {
114         rc = 0;
115     }
116     g_free(val);
117     return rc;
118 }
119
120 int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
121 {
122     return xenstore_write_str(xendev->be, node, val);
123 }
124
125 int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
126 {
127     return xenstore_write_int(xendev->be, node, ival);
128 }
129
130 int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
131 {
132     return xenstore_write_int64(xendev->be, node, ival);
133 }
134
135 char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
136 {
137     return xenstore_read_str(xendev->be, node);
138 }
139
140 int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
141 {
142     return xenstore_read_int(xendev->be, node, ival);
143 }
144
145 char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
146 {
147     return xenstore_read_str(xendev->fe, node);
148 }
149
150 int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
151 {
152     return xenstore_read_int(xendev->fe, node, ival);
153 }
154
155 int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, uint64_t *uval)
156 {
157     return xenstore_read_uint64(xendev->fe, node, uval);
158 }
159
160 /* ------------------------------------------------------------- */
161
162 const char *xenbus_strstate(enum xenbus_state state)
163 {
164     static const char *const name[] = {
165         [ XenbusStateUnknown      ] = "Unknown",
166         [ XenbusStateInitialising ] = "Initialising",
167         [ XenbusStateInitWait     ] = "InitWait",
168         [ XenbusStateInitialised  ] = "Initialised",
169         [ XenbusStateConnected    ] = "Connected",
170         [ XenbusStateClosing      ] = "Closing",
171         [ XenbusStateClosed       ] = "Closed",
172     };
173     return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
174 }
175
176 int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
177 {
178     int rc;
179
180     rc = xenstore_write_be_int(xendev, "state", state);
181     if (rc < 0) {
182         return rc;
183     }
184     xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
185                   xenbus_strstate(xendev->be_state), xenbus_strstate(state));
186     xendev->be_state = state;
187     return 0;
188 }
189
190 /* ------------------------------------------------------------- */
191
192 struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
193 {
194     struct XenDevice *xendev;
195
196     QTAILQ_FOREACH(xendev, &xendevs, next) {
197         if (xendev->dom != dom) {
198             continue;
199         }
200         if (xendev->dev != dev) {
201             continue;
202         }
203         if (strcmp(xendev->type, type) != 0) {
204             continue;
205         }
206         return xendev;
207     }
208     return NULL;
209 }
210
211 /*
212  * get xen backend device, allocate a new one if it doesn't exist.
213  */
214 static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
215                                            struct XenDevOps *ops)
216 {
217     struct XenDevice *xendev;
218
219     xendev = xen_be_find_xendev(type, dom, dev);
220     if (xendev) {
221         return xendev;
222     }
223
224     /* init new xendev */
225     xendev = g_malloc0(ops->size);
226     xendev->type  = type;
227     xendev->dom   = dom;
228     xendev->dev   = dev;
229     xendev->ops   = ops;
230
231     snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d",
232              xendev->type, xendev->dom, xendev->dev);
233     snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
234              xendev->type, xendev->dev);
235
236     xendev->debug      = debug;
237     xendev->local_port = -1;
238
239     xendev->evtchndev = xenevtchn_open(NULL, 0);
240     if (xendev->evtchndev == NULL) {
241         xen_be_printf(NULL, 0, "can't open evtchn device\n");
242         g_free(xendev);
243         return NULL;
244     }
245     fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
246
247     if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
248         xendev->gnttabdev = xengnttab_open(NULL, 0);
249         if (xendev->gnttabdev == NULL) {
250             xen_be_printf(NULL, 0, "can't open gnttab device\n");
251             xenevtchn_close(xendev->evtchndev);
252             g_free(xendev);
253             return NULL;
254         }
255     } else {
256         xendev->gnttabdev = NULL;
257     }
258
259     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
260
261     if (xendev->ops->alloc) {
262         xendev->ops->alloc(xendev);
263     }
264
265     return xendev;
266 }
267
268 /*
269  * release xen backend device.
270  */
271 static struct XenDevice *xen_be_del_xendev(int dom, int dev)
272 {
273     struct XenDevice *xendev, *xnext;
274
275     /*
276      * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but
277      * we save the next pointer in xnext because we might free xendev.
278      */
279     xnext = xendevs.tqh_first;
280     while (xnext) {
281         xendev = xnext;
282         xnext = xendev->next.tqe_next;
283
284         if (xendev->dom != dom) {
285             continue;
286         }
287         if (xendev->dev != dev && dev != -1) {
288             continue;
289         }
290
291         if (xendev->ops->free) {
292             xendev->ops->free(xendev);
293         }
294
295         if (xendev->fe) {
296             char token[XEN_BUFSIZE];
297             snprintf(token, sizeof(token), "fe:%p", xendev);
298             xs_unwatch(xenstore, xendev->fe, token);
299             g_free(xendev->fe);
300         }
301
302         if (xendev->evtchndev != NULL) {
303             xenevtchn_close(xendev->evtchndev);
304         }
305         if (xendev->gnttabdev != NULL) {
306             xengnttab_close(xendev->gnttabdev);
307         }
308
309         QTAILQ_REMOVE(&xendevs, xendev, next);
310         g_free(xendev);
311     }
312     return NULL;
313 }
314
315 /*
316  * Sync internal data structures on xenstore updates.
317  * Node specifies the changed field.  node = NULL means
318  * update all fields (used for initialization).
319  */
320 static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
321 {
322     if (node == NULL  ||  strcmp(node, "online") == 0) {
323         if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
324             xendev->online = 0;
325         }
326     }
327
328     if (node) {
329         xen_be_printf(xendev, 2, "backend update: %s\n", node);
330         if (xendev->ops->backend_changed) {
331             xendev->ops->backend_changed(xendev, node);
332         }
333     }
334 }
335
336 static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
337 {
338     int fe_state;
339
340     if (node == NULL  ||  strcmp(node, "state") == 0) {
341         if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) {
342             fe_state = XenbusStateUnknown;
343         }
344         if (xendev->fe_state != fe_state) {
345             xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
346                           xenbus_strstate(xendev->fe_state),
347                           xenbus_strstate(fe_state));
348         }
349         xendev->fe_state = fe_state;
350     }
351     if (node == NULL  ||  strcmp(node, "protocol") == 0) {
352         g_free(xendev->protocol);
353         xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
354         if (xendev->protocol) {
355             xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
356         }
357     }
358
359     if (node) {
360         xen_be_printf(xendev, 2, "frontend update: %s\n", node);
361         if (xendev->ops->frontend_changed) {
362             xendev->ops->frontend_changed(xendev, node);
363         }
364     }
365 }
366
367 /* ------------------------------------------------------------- */
368 /* Check for possible state transitions and perform them.        */
369
370 /*
371  * Initial xendev setup.  Read frontend path, register watch for it.
372  * Should succeed once xend finished setting up the backend device.
373  *
374  * Also sets initial state (-> Initializing) when done.  Which
375  * only affects the xendev->be_state variable as xenbus should
376  * already be put into that state by xend.
377  */
378 static int xen_be_try_setup(struct XenDevice *xendev)
379 {
380     char token[XEN_BUFSIZE];
381     int be_state;
382
383     if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
384         xen_be_printf(xendev, 0, "reading backend state failed\n");
385         return -1;
386     }
387
388     if (be_state != XenbusStateInitialising) {
389         xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
390                       xenbus_strstate(be_state));
391         return -1;
392     }
393
394     xendev->fe = xenstore_read_be_str(xendev, "frontend");
395     if (xendev->fe == NULL) {
396         xen_be_printf(xendev, 0, "reading frontend path failed\n");
397         return -1;
398     }
399
400     /* setup frontend watch */
401     snprintf(token, sizeof(token), "fe:%p", xendev);
402     if (!xs_watch(xenstore, xendev->fe, token)) {
403         xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
404                       xendev->fe);
405         return -1;
406     }
407     xen_be_set_state(xendev, XenbusStateInitialising);
408
409     xen_be_backend_changed(xendev, NULL);
410     xen_be_frontend_changed(xendev, NULL);
411     return 0;
412 }
413
414 /*
415  * Try initialize xendev.  Prepare everything the backend can do
416  * without synchronizing with the frontend.  Fakes hotplug-status.  No
417  * hotplug involved here because this is about userspace drivers, thus
418  * there are kernel backend devices which could invoke hotplug.
419  *
420  * Goes to InitWait on success.
421  */
422 static int xen_be_try_init(struct XenDevice *xendev)
423 {
424     int rc = 0;
425
426     if (!xendev->online) {
427         xen_be_printf(xendev, 1, "not online\n");
428         return -1;
429     }
430
431     if (xendev->ops->init) {
432         rc = xendev->ops->init(xendev);
433     }
434     if (rc != 0) {
435         xen_be_printf(xendev, 1, "init() failed\n");
436         return rc;
437     }
438
439     xenstore_write_be_str(xendev, "hotplug-status", "connected");
440     xen_be_set_state(xendev, XenbusStateInitWait);
441     return 0;
442 }
443
444 /*
445  * Try to initialise xendev.  Depends on the frontend being ready
446  * for it (shared ring and evtchn info in xenstore, state being
447  * Initialised or Connected).
448  *
449  * Goes to Connected on success.
450  */
451 static int xen_be_try_initialise(struct XenDevice *xendev)
452 {
453     int rc = 0;
454
455     if (xendev->fe_state != XenbusStateInitialised  &&
456         xendev->fe_state != XenbusStateConnected) {
457         if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
458             xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
459         } else {
460             xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
461             return -1;
462         }
463     }
464
465     if (xendev->ops->initialise) {
466         rc = xendev->ops->initialise(xendev);
467     }
468     if (rc != 0) {
469         xen_be_printf(xendev, 0, "initialise() failed\n");
470         return rc;
471     }
472
473     xen_be_set_state(xendev, XenbusStateConnected);
474     return 0;
475 }
476
477 /*
478  * Try to let xendev know that it is connected.  Depends on the
479  * frontend being Connected.  Note that this may be called more
480  * than once since the backend state is not modified.
481  */
482 static void xen_be_try_connected(struct XenDevice *xendev)
483 {
484     if (!xendev->ops->connected) {
485         return;
486     }
487
488     if (xendev->fe_state != XenbusStateConnected) {
489         if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
490             xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
491         } else {
492             xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
493             return;
494         }
495     }
496
497     xendev->ops->connected(xendev);
498 }
499
500 /*
501  * Teardown connection.
502  *
503  * Goes to Closed when done.
504  */
505 static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
506 {
507     if (xendev->be_state != XenbusStateClosing &&
508         xendev->be_state != XenbusStateClosed  &&
509         xendev->ops->disconnect) {
510         xendev->ops->disconnect(xendev);
511     }
512     if (xendev->be_state != state) {
513         xen_be_set_state(xendev, state);
514     }
515 }
516
517 /*
518  * Try to reset xendev, for reconnection by another frontend instance.
519  */
520 static int xen_be_try_reset(struct XenDevice *xendev)
521 {
522     if (xendev->fe_state != XenbusStateInitialising) {
523         return -1;
524     }
525
526     xen_be_printf(xendev, 1, "device reset (for re-connect)\n");
527     xen_be_set_state(xendev, XenbusStateInitialising);
528     return 0;
529 }
530
531 /*
532  * state change dispatcher function
533  */
534 void xen_be_check_state(struct XenDevice *xendev)
535 {
536     int rc = 0;
537
538     /* frontend may request shutdown from almost anywhere */
539     if (xendev->fe_state == XenbusStateClosing ||
540         xendev->fe_state == XenbusStateClosed) {
541         xen_be_disconnect(xendev, xendev->fe_state);
542         return;
543     }
544
545     /* check for possible backend state transitions */
546     for (;;) {
547         switch (xendev->be_state) {
548         case XenbusStateUnknown:
549             rc = xen_be_try_setup(xendev);
550             break;
551         case XenbusStateInitialising:
552             rc = xen_be_try_init(xendev);
553             break;
554         case XenbusStateInitWait:
555             rc = xen_be_try_initialise(xendev);
556             break;
557         case XenbusStateConnected:
558             /* xendev->be_state doesn't change */
559             xen_be_try_connected(xendev);
560             rc = -1;
561             break;
562         case XenbusStateClosed:
563             rc = xen_be_try_reset(xendev);
564             break;
565         default:
566             rc = -1;
567         }
568         if (rc != 0) {
569             break;
570         }
571     }
572 }
573
574 /* ------------------------------------------------------------- */
575
576 static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
577 {
578     struct XenDevice *xendev;
579     char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
580     char **dev = NULL;
581     unsigned int cdev, j;
582
583     /* setup watch */
584     snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
585     snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
586     if (!xs_watch(xenstore, path, token)) {
587         xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
588         return -1;
589     }
590
591     /* look for backends */
592     dev = xs_directory(xenstore, 0, path, &cdev);
593     if (!dev) {
594         return 0;
595     }
596     for (j = 0; j < cdev; j++) {
597         xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
598         if (xendev == NULL) {
599             continue;
600         }
601         xen_be_check_state(xendev);
602     }
603     free(dev);
604     return 0;
605 }
606
607 static void xenstore_update_be(char *watch, char *type, int dom,
608                                struct XenDevOps *ops)
609 {
610     struct XenDevice *xendev;
611     char path[XEN_BUFSIZE], *bepath;
612     unsigned int len, dev;
613
614     len = snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
615     if (strncmp(path, watch, len) != 0) {
616         return;
617     }
618     if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
619         strcpy(path, "");
620         if (sscanf(watch+len, "/%u", &dev) != 1) {
621             dev = -1;
622         }
623     }
624     if (dev == -1) {
625         return;
626     }
627
628     xendev = xen_be_get_xendev(type, dom, dev, ops);
629     if (xendev != NULL) {
630         bepath = xs_read(xenstore, 0, xendev->be, &len);
631         if (bepath == NULL) {
632             xen_be_del_xendev(dom, dev);
633         } else {
634             free(bepath);
635             xen_be_backend_changed(xendev, path);
636             xen_be_check_state(xendev);
637         }
638     }
639 }
640
641 static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
642 {
643     char *node;
644     unsigned int len;
645
646     len = strlen(xendev->fe);
647     if (strncmp(xendev->fe, watch, len) != 0) {
648         return;
649     }
650     if (watch[len] != '/') {
651         return;
652     }
653     node = watch + len + 1;
654
655     xen_be_frontend_changed(xendev, node);
656     xen_be_check_state(xendev);
657 }
658
659 static void xenstore_update(void *unused)
660 {
661     char **vec = NULL;
662     intptr_t type, ops, ptr;
663     unsigned int dom, count;
664
665     vec = xs_read_watch(xenstore, &count);
666     if (vec == NULL) {
667         goto cleanup;
668     }
669
670     if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
671                &type, &dom, &ops) == 3) {
672         xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
673     }
674     if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
675         xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
676     }
677
678 cleanup:
679     free(vec);
680 }
681
682 static void xen_be_evtchn_event(void *opaque)
683 {
684     struct XenDevice *xendev = opaque;
685     evtchn_port_t port;
686
687     port = xenevtchn_pending(xendev->evtchndev);
688     if (port != xendev->local_port) {
689         xen_be_printf(xendev, 0,
690                       "xenevtchn_pending returned %d (expected %d)\n",
691                       port, xendev->local_port);
692         return;
693     }
694     xenevtchn_unmask(xendev->evtchndev, port);
695
696     if (xendev->ops->event) {
697         xendev->ops->event(xendev);
698     }
699 }
700
701 /* -------------------------------------------------------------------- */
702
703 int xen_be_init(void)
704 {
705     xenstore = xs_daemon_open();
706     if (!xenstore) {
707         xen_be_printf(NULL, 0, "can't connect to xenstored\n");
708         return -1;
709     }
710
711     qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
712
713     if (xen_xc == NULL || xen_fmem == NULL) {
714         /* Check if xen_init() have been called */
715         goto err;
716     }
717     return 0;
718
719 err:
720     qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
721     xs_daemon_close(xenstore);
722     xenstore = NULL;
723
724     return -1;
725 }
726
727 int xen_be_register(const char *type, struct XenDevOps *ops)
728 {
729     return xenstore_scan(type, xen_domid, ops);
730 }
731
732 int xen_be_bind_evtchn(struct XenDevice *xendev)
733 {
734     if (xendev->local_port != -1) {
735         return 0;
736     }
737     xendev->local_port = xenevtchn_bind_interdomain
738         (xendev->evtchndev, xendev->dom, xendev->remote_port);
739     if (xendev->local_port == -1) {
740         xen_be_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
741         return -1;
742     }
743     xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
744     qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
745                         xen_be_evtchn_event, NULL, xendev);
746     return 0;
747 }
748
749 void xen_be_unbind_evtchn(struct XenDevice *xendev)
750 {
751     if (xendev->local_port == -1) {
752         return;
753     }
754     qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
755     xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
756     xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
757     xendev->local_port = -1;
758 }
759
760 int xen_be_send_notify(struct XenDevice *xendev)
761 {
762     return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
763 }
764
765 /*
766  * msg_level:
767  *  0 == errors (stderr + logfile).
768  *  1 == informative debug messages (logfile only).
769  *  2 == noisy debug messages (logfile only).
770  *  3 == will flood your log (logfile only).
771  */
772 void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
773 {
774     va_list args;
775
776     if (xendev) {
777         if (msg_level > xendev->debug) {
778             return;
779         }
780         qemu_log("xen be: %s: ", xendev->name);
781         if (msg_level == 0) {
782             fprintf(stderr, "xen be: %s: ", xendev->name);
783         }
784     } else {
785         if (msg_level > debug) {
786             return;
787         }
788         qemu_log("xen be core: ");
789         if (msg_level == 0) {
790             fprintf(stderr, "xen be core: ");
791         }
792     }
793     va_start(args, fmt);
794     qemu_log_vprintf(fmt, args);
795     va_end(args);
796     if (msg_level == 0) {
797         va_start(args, fmt);
798         vfprintf(stderr, fmt, args);
799         va_end(args);
800     }
801     qemu_log_flush();
802 }