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