xref: /openbmc/qemu/hw/xen/xen-bus.c (revision 1f2146f7)
1  /*
2   * Copyright (c) 2018  Citrix Systems Inc.
3   *
4   * This work is licensed under the terms of the GNU GPL, version 2 or later.
5   * See the COPYING file in the top-level directory.
6   */
7  
8  #include "qemu/osdep.h"
9  #include "qemu/main-loop.h"
10  #include "qemu/module.h"
11  #include "qemu/uuid.h"
12  #include "hw/qdev-properties.h"
13  #include "hw/sysbus.h"
14  #include "hw/xen/xen.h"
15  #include "hw/xen/xen-backend.h"
16  #include "hw/xen/xen-bus.h"
17  #include "hw/xen/xen-bus-helper.h"
18  #include "monitor/monitor.h"
19  #include "qapi/error.h"
20  #include "qapi/qmp/qdict.h"
21  #include "sysemu/sysemu.h"
22  #include "trace.h"
23  
24  static char *xen_device_get_backend_path(XenDevice *xendev)
25  {
26      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
27      XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
28      const char *type = object_get_typename(OBJECT(xendev));
29      const char *backend = xendev_class->backend;
30  
31      if (!backend) {
32          backend = type;
33      }
34  
35      return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
36                             xenbus->backend_id, backend, xendev->frontend_id,
37                             xendev->name);
38  }
39  
40  static char *xen_device_get_frontend_path(XenDevice *xendev)
41  {
42      XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
43      const char *type = object_get_typename(OBJECT(xendev));
44      const char *device = xendev_class->device;
45  
46      if (!device) {
47          device = type;
48      }
49  
50      return g_strdup_printf("/local/domain/%u/device/%s/%s",
51                             xendev->frontend_id, device, xendev->name);
52  }
53  
54  static void xen_device_unplug(XenDevice *xendev, Error **errp)
55  {
56      ERRP_GUARD();
57      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
58      const char *type = object_get_typename(OBJECT(xendev));
59      xs_transaction_t tid;
60  
61      trace_xen_device_unplug(type, xendev->name);
62  
63      /* Mimic the way the Xen toolstack does an unplug */
64  again:
65      tid = qemu_xen_xs_transaction_start(xenbus->xsh);
66      if (tid == XBT_NULL) {
67          error_setg_errno(errp, errno, "failed xs_transaction_start");
68          return;
69      }
70  
71      xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
72                     errp, "%u", 0);
73      if (*errp) {
74          goto abort;
75      }
76  
77      xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
78                     errp, "%u", XenbusStateClosing);
79      if (*errp) {
80          goto abort;
81      }
82  
83      if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
84          if (errno == EAGAIN) {
85              goto again;
86          }
87  
88          error_setg_errno(errp, errno, "failed xs_transaction_end");
89      }
90  
91      return;
92  
93  abort:
94      /*
95       * We only abort if there is already a failure so ignore any error
96       * from ending the transaction.
97       */
98      qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
99  }
100  
101  static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
102  {
103      XenDevice *xendev = XEN_DEVICE(dev);
104  
105      monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
106                     indent, "", xendev->name, xendev->frontend_id);
107  }
108  
109  static char *xen_bus_get_dev_path(DeviceState *dev)
110  {
111      return xen_device_get_backend_path(XEN_DEVICE(dev));
112  }
113  
114  static void xen_bus_backend_create(XenBus *xenbus, const char *type,
115                                     const char *name, char *path,
116                                     Error **errp)
117  {
118      ERRP_GUARD();
119      xs_transaction_t tid;
120      char **key;
121      QDict *opts;
122      unsigned int i, n;
123  
124      trace_xen_bus_backend_create(type, path);
125  
126  again:
127      tid = qemu_xen_xs_transaction_start(xenbus->xsh);
128      if (tid == XBT_NULL) {
129          error_setg(errp, "failed xs_transaction_start");
130          return;
131      }
132  
133      key = qemu_xen_xs_directory(xenbus->xsh, tid, path, &n);
134      if (!key) {
135          if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, true)) {
136              error_setg_errno(errp, errno, "failed xs_transaction_end");
137          }
138          return;
139      }
140  
141      opts = qdict_new();
142      for (i = 0; i < n; i++) {
143          char *val;
144  
145          /*
146           * Assume anything found in the xenstore backend area, other than
147           * the keys created for a generic XenDevice, are parameters
148           * to be used to configure the backend.
149           */
150          if (!strcmp(key[i], "state") ||
151              !strcmp(key[i], "online") ||
152              !strcmp(key[i], "frontend") ||
153              !strcmp(key[i], "frontend-id") ||
154              !strcmp(key[i], "hotplug-status"))
155              continue;
156  
157          if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
158                            &val) == 1) {
159              qdict_put_str(opts, key[i], val);
160              free(val);
161          }
162      }
163  
164      free(key);
165  
166      if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
167          qobject_unref(opts);
168  
169          if (errno == EAGAIN) {
170              goto again;
171          }
172  
173          error_setg_errno(errp, errno, "failed xs_transaction_end");
174          return;
175      }
176  
177      xen_backend_device_create(xenbus, type, name, opts, errp);
178      qobject_unref(opts);
179  
180      if (*errp) {
181          error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
182      }
183  }
184  
185  static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
186  {
187      char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
188      char **backend;
189      unsigned int i, n;
190  
191      trace_xen_bus_type_enumerate(type);
192  
193      backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
194      if (!backend) {
195          goto out;
196      }
197  
198      for (i = 0; i < n; i++) {
199          char *backend_path = g_strdup_printf("%s/%s", domain_path,
200                                               backend[i]);
201          enum xenbus_state state;
202          unsigned int online;
203  
204          if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
205                            NULL, "%u", &state) != 1)
206              state = XenbusStateUnknown;
207  
208          if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
209                            NULL, "%u", &online) != 1)
210              online = 0;
211  
212          if (online && state == XenbusStateInitialising) {
213              Error *local_err = NULL;
214  
215              xen_bus_backend_create(xenbus, type, backend[i], backend_path,
216                                     &local_err);
217              if (local_err) {
218                  error_report_err(local_err);
219              }
220          }
221  
222          g_free(backend_path);
223      }
224  
225      free(backend);
226  
227  out:
228      g_free(domain_path);
229  }
230  
231  static void xen_bus_enumerate(XenBus *xenbus)
232  {
233      char **type;
234      unsigned int i, n;
235  
236      trace_xen_bus_enumerate();
237  
238      type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
239      if (!type) {
240          return;
241      }
242  
243      for (i = 0; i < n; i++) {
244          xen_bus_type_enumerate(xenbus, type[i]);
245      }
246  
247      free(type);
248  }
249  
250  static void xen_bus_device_cleanup(XenDevice *xendev)
251  {
252      const char *type = object_get_typename(OBJECT(xendev));
253      Error *local_err = NULL;
254  
255      trace_xen_bus_device_cleanup(type, xendev->name);
256  
257      g_assert(!xendev->backend_online);
258  
259      if (!xen_backend_try_device_destroy(xendev, &local_err)) {
260          object_unparent(OBJECT(xendev));
261      }
262  
263      if (local_err) {
264          error_report_err(local_err);
265      }
266  }
267  
268  static void xen_bus_cleanup(XenBus *xenbus)
269  {
270      XenDevice *xendev, *next;
271  
272      trace_xen_bus_cleanup();
273  
274      QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
275          g_assert(xendev->inactive);
276          QLIST_REMOVE(xendev, list);
277          xen_bus_device_cleanup(xendev);
278      }
279  }
280  
281  static void xen_bus_backend_changed(void *opaque, const char *path)
282  {
283      XenBus *xenbus = opaque;
284  
285      xen_bus_enumerate(xenbus);
286      xen_bus_cleanup(xenbus);
287  }
288  
289  static void xen_bus_unrealize(BusState *bus)
290  {
291      XenBus *xenbus = XEN_BUS(bus);
292  
293      trace_xen_bus_unrealize();
294  
295      if (xenbus->backend_watch) {
296          unsigned int i;
297  
298          for (i = 0; i < xenbus->backend_types; i++) {
299              if (xenbus->backend_watch[i]) {
300                  xs_node_unwatch(xenbus->xsh, xenbus->backend_watch[i]);
301              }
302          }
303  
304          g_free(xenbus->backend_watch);
305          xenbus->backend_watch = NULL;
306      }
307  
308      if (xenbus->xsh) {
309          qemu_xen_xs_close(xenbus->xsh);
310      }
311  }
312  
313  static void xen_bus_realize(BusState *bus, Error **errp)
314  {
315      char *key = g_strdup_printf("%u", xen_domid);
316      XenBus *xenbus = XEN_BUS(bus);
317      unsigned int domid;
318      const char **type;
319      unsigned int i;
320      Error *local_err = NULL;
321  
322      trace_xen_bus_realize();
323  
324      xenbus->xsh = qemu_xen_xs_open();
325      if (!xenbus->xsh) {
326          error_setg_errno(errp, errno, "failed xs_open");
327          goto fail;
328      }
329  
330      if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
331                        "domid", NULL, "%u", &domid) == 1) {
332          xenbus->backend_id = domid;
333      } else {
334          xenbus->backend_id = 0; /* Assume lack of node means dom0 */
335      }
336  
337      module_call_init(MODULE_INIT_XEN_BACKEND);
338  
339      type = xen_backend_get_types(&xenbus->backend_types);
340      xenbus->backend_watch = g_new(struct qemu_xs_watch *,
341                                    xenbus->backend_types);
342  
343      for (i = 0; i < xenbus->backend_types; i++) {
344          char *node = g_strdup_printf("backend/%s", type[i]);
345  
346          xenbus->backend_watch[i] =
347              xs_node_watch(xenbus->xsh, node, key, xen_bus_backend_changed,
348                            xenbus, &local_err);
349          if (local_err) {
350              /* This need not be treated as a hard error so don't propagate */
351              error_reportf_err(local_err,
352                                "failed to set up '%s' enumeration watch: ",
353                                type[i]);
354          }
355  
356          g_free(node);
357      }
358  
359      g_free(type);
360      g_free(key);
361      return;
362  
363  fail:
364      xen_bus_unrealize(bus);
365      g_free(key);
366  }
367  
368  static void xen_bus_unplug_request(HotplugHandler *hotplug,
369                                     DeviceState *dev,
370                                     Error **errp)
371  {
372      XenDevice *xendev = XEN_DEVICE(dev);
373  
374      xen_device_unplug(xendev, errp);
375  }
376  
377  static void xen_bus_class_init(ObjectClass *class, void *data)
378  {
379      BusClass *bus_class = BUS_CLASS(class);
380      HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
381  
382      bus_class->print_dev = xen_bus_print_dev;
383      bus_class->get_dev_path = xen_bus_get_dev_path;
384      bus_class->realize = xen_bus_realize;
385      bus_class->unrealize = xen_bus_unrealize;
386  
387      hotplug_class->unplug_request = xen_bus_unplug_request;
388  }
389  
390  static const TypeInfo xen_bus_type_info = {
391      .name = TYPE_XEN_BUS,
392      .parent = TYPE_BUS,
393      .instance_size = sizeof(XenBus),
394      .class_size = sizeof(XenBusClass),
395      .class_init = xen_bus_class_init,
396      .interfaces = (InterfaceInfo[]) {
397          { TYPE_HOTPLUG_HANDLER },
398          { }
399      },
400  };
401  
402  void xen_device_backend_printf(XenDevice *xendev, const char *key,
403                                 const char *fmt, ...)
404  {
405      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
406      Error *local_err = NULL;
407      va_list ap;
408  
409      g_assert(xenbus->xsh);
410  
411      va_start(ap, fmt);
412      xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
413                      &local_err, fmt, ap);
414      va_end(ap);
415  
416      if (local_err) {
417          error_report_err(local_err);
418      }
419  }
420  
421  G_GNUC_SCANF(3, 4)
422  static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
423                                      const char *fmt, ...)
424  {
425      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
426      va_list ap;
427      int rc;
428  
429      g_assert(xenbus->xsh);
430  
431      va_start(ap, fmt);
432      rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
433                          NULL, fmt, ap);
434      va_end(ap);
435  
436      return rc;
437  }
438  
439  void xen_device_backend_set_state(XenDevice *xendev,
440                                    enum xenbus_state state)
441  {
442      const char *type = object_get_typename(OBJECT(xendev));
443  
444      if (xendev->backend_state == state) {
445          return;
446      }
447  
448      trace_xen_device_backend_state(type, xendev->name,
449                                     xs_strstate(state));
450  
451      xendev->backend_state = state;
452      xen_device_backend_printf(xendev, "state", "%u", state);
453  }
454  
455  enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
456  {
457      return xendev->backend_state;
458  }
459  
460  static void xen_device_backend_set_online(XenDevice *xendev, bool online)
461  {
462      const char *type = object_get_typename(OBJECT(xendev));
463  
464      if (xendev->backend_online == online) {
465          return;
466      }
467  
468      trace_xen_device_backend_online(type, xendev->name, online);
469  
470      xendev->backend_online = online;
471      xen_device_backend_printf(xendev, "online", "%u", online);
472  }
473  
474  /*
475   * Tell from the state whether the frontend is likely alive,
476   * i.e. it will react to a change of state of the backend.
477   */
478  static bool xen_device_frontend_is_active(XenDevice *xendev)
479  {
480      switch (xendev->frontend_state) {
481      case XenbusStateInitWait:
482      case XenbusStateInitialised:
483      case XenbusStateConnected:
484      case XenbusStateClosing:
485          return true;
486      default:
487          return false;
488      }
489  }
490  
491  static void xen_device_backend_changed(void *opaque, const char *path)
492  {
493      XenDevice *xendev = opaque;
494      const char *type = object_get_typename(OBJECT(xendev));
495      enum xenbus_state state;
496      unsigned int online;
497  
498      trace_xen_device_backend_changed(type, xendev->name);
499  
500      if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
501          state = XenbusStateUnknown;
502      }
503  
504      xen_device_backend_set_state(xendev, state);
505  
506      if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
507          online = 0;
508      }
509  
510      xen_device_backend_set_online(xendev, !!online);
511  
512      /*
513       * If the toolstack (or unplug request callback) has set the backend
514       * state to Closing, but there is no active frontend then set the
515       * backend state to Closed.
516       */
517      if (state == XenbusStateClosing &&
518          !xen_device_frontend_is_active(xendev)) {
519          xen_device_backend_set_state(xendev, XenbusStateClosed);
520      }
521  
522      /*
523       * If a backend is still 'online' then we should leave it alone but,
524       * if a backend is not 'online', then the device is a candidate
525       * for destruction. Hence add it to the 'inactive' list to be cleaned
526       * by xen_bus_cleanup().
527       */
528      if (!online &&
529          (state == XenbusStateClosed ||  state == XenbusStateInitialising ||
530           state == XenbusStateInitWait || state == XenbusStateUnknown) &&
531          !xendev->inactive) {
532          XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
533  
534          xendev->inactive = true;
535          QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
536  
537          /*
538           * Re-write the state to cause a XenBus backend_watch notification,
539           * resulting in a call to xen_bus_cleanup().
540           */
541          xen_device_backend_printf(xendev, "state", "%u", state);
542      }
543  }
544  
545  static void xen_device_backend_create(XenDevice *xendev, Error **errp)
546  {
547      ERRP_GUARD();
548      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
549  
550      xendev->backend_path = xen_device_get_backend_path(xendev);
551  
552      g_assert(xenbus->xsh);
553  
554      xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path,
555                     xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp);
556      if (*errp) {
557          error_prepend(errp, "failed to create backend: ");
558          return;
559      }
560  
561      xendev->backend_state_watch =
562          xs_node_watch(xendev->xsh, xendev->backend_path,
563                        "state", xen_device_backend_changed, xendev,
564                        errp);
565      if (*errp) {
566          error_prepend(errp, "failed to watch backend state: ");
567          return;
568      }
569  
570      xendev->backend_online_watch =
571          xs_node_watch(xendev->xsh, xendev->backend_path,
572                        "online", xen_device_backend_changed, xendev,
573                        errp);
574      if (*errp) {
575          error_prepend(errp, "failed to watch backend online: ");
576          return;
577      }
578  }
579  
580  static void xen_device_backend_destroy(XenDevice *xendev)
581  {
582      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
583      Error *local_err = NULL;
584  
585      if (xendev->backend_online_watch) {
586          xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
587          xendev->backend_online_watch = NULL;
588      }
589  
590      if (xendev->backend_state_watch) {
591          xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
592          xendev->backend_state_watch = NULL;
593      }
594  
595      if (!xendev->backend_path) {
596          return;
597      }
598  
599      g_assert(xenbus->xsh);
600  
601      xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
602                      &local_err);
603      g_free(xendev->backend_path);
604      xendev->backend_path = NULL;
605  
606      if (local_err) {
607          error_report_err(local_err);
608      }
609  }
610  
611  void xen_device_frontend_printf(XenDevice *xendev, const char *key,
612                                  const char *fmt, ...)
613  {
614      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
615      Error *local_err = NULL;
616      va_list ap;
617  
618      g_assert(xenbus->xsh);
619  
620      va_start(ap, fmt);
621      xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
622                      &local_err, fmt, ap);
623      va_end(ap);
624  
625      if (local_err) {
626          error_report_err(local_err);
627      }
628  }
629  
630  int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
631                                const char *fmt, ...)
632  {
633      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
634      va_list ap;
635      int rc;
636  
637      g_assert(xenbus->xsh);
638  
639      va_start(ap, fmt);
640      rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
641                          NULL, fmt, ap);
642      va_end(ap);
643  
644      return rc;
645  }
646  
647  static void xen_device_frontend_set_state(XenDevice *xendev,
648                                            enum xenbus_state state,
649                                            bool publish)
650  {
651      const char *type = object_get_typename(OBJECT(xendev));
652  
653      if (xendev->frontend_state == state) {
654          return;
655      }
656  
657      trace_xen_device_frontend_state(type, xendev->name,
658                                      xs_strstate(state));
659  
660      xendev->frontend_state = state;
661      if (publish) {
662          xen_device_frontend_printf(xendev, "state", "%u", state);
663      }
664  }
665  
666  static void xen_device_frontend_changed(void *opaque, const char *path)
667  {
668      XenDevice *xendev = opaque;
669      XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
670      const char *type = object_get_typename(OBJECT(xendev));
671      enum xenbus_state state;
672  
673      trace_xen_device_frontend_changed(type, xendev->name);
674  
675      if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
676          state = XenbusStateUnknown;
677      }
678  
679      xen_device_frontend_set_state(xendev, state, false);
680  
681      if (state == XenbusStateInitialising &&
682          xendev->backend_state == XenbusStateClosed &&
683          xendev->backend_online) {
684          /*
685           * The frontend is re-initializing so switch back to
686           * InitWait.
687           */
688          xen_device_backend_set_state(xendev, XenbusStateInitWait);
689          return;
690      }
691  
692      if (xendev_class->frontend_changed) {
693          Error *local_err = NULL;
694  
695          xendev_class->frontend_changed(xendev, state, &local_err);
696  
697          if (local_err) {
698              error_reportf_err(local_err, "frontend change error: ");
699          }
700      }
701  }
702  
703  static bool xen_device_frontend_exists(XenDevice *xendev)
704  {
705      enum xenbus_state state;
706  
707      return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
708  }
709  
710  static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
711  {
712      ERRP_GUARD();
713      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
714  
715      xendev->frontend_path = xen_device_get_frontend_path(xendev);
716  
717      /*
718       * The frontend area may have already been created by a legacy
719       * toolstack.
720       */
721      if (!xen_device_frontend_exists(xendev)) {
722          g_assert(xenbus->xsh);
723  
724          xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
725                         xendev->frontend_id, xenbus->backend_id,
726                         XS_PERM_READ | XS_PERM_WRITE, errp);
727          if (*errp) {
728              error_prepend(errp, "failed to create frontend: ");
729              return;
730          }
731      }
732  
733      xendev->frontend_state_watch =
734          xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
735                        xen_device_frontend_changed, xendev, errp);
736      if (*errp) {
737          error_prepend(errp, "failed to watch frontend state: ");
738      }
739  }
740  
741  static void xen_device_frontend_destroy(XenDevice *xendev)
742  {
743      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
744      Error *local_err = NULL;
745  
746      if (xendev->frontend_state_watch) {
747          xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
748          xendev->frontend_state_watch = NULL;
749      }
750  
751      if (!xendev->frontend_path) {
752          return;
753      }
754  
755      g_assert(xenbus->xsh);
756  
757      xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
758                      &local_err);
759      g_free(xendev->frontend_path);
760      xendev->frontend_path = NULL;
761  
762      if (local_err) {
763          error_report_err(local_err);
764      }
765  }
766  
767  void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
768                                     Error **errp)
769  {
770      if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
771          error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
772      }
773  }
774  
775  void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
776                                  unsigned int nr_refs, int prot,
777                                  Error **errp)
778  {
779      void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
780                                           xendev->frontend_id, refs, prot);
781  
782      if (!map) {
783          error_setg_errno(errp, errno,
784                           "xengnttab_map_domain_grant_refs failed");
785      }
786  
787      return map;
788  }
789  
790  void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
791                                   unsigned int nr_refs, Error **errp)
792  {
793      if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
794          error_setg_errno(errp, errno, "xengnttab_unmap failed");
795      }
796  }
797  
798  void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
799                                  XenDeviceGrantCopySegment segs[],
800                                  unsigned int nr_segs, Error **errp)
801  {
802      qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
803                                 (XenGrantCopySegment *)segs, nr_segs, errp);
804  }
805  
806  struct XenEventChannel {
807      QLIST_ENTRY(XenEventChannel) list;
808      AioContext *ctx;
809      xenevtchn_handle *xeh;
810      evtchn_port_t local_port;
811      XenEventHandler handler;
812      void *opaque;
813  };
814  
815  static bool xen_device_poll(void *opaque)
816  {
817      XenEventChannel *channel = opaque;
818  
819      return channel->handler(channel->opaque);
820  }
821  
822  static void xen_device_event(void *opaque)
823  {
824      XenEventChannel *channel = opaque;
825      unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
826  
827      if (port == channel->local_port) {
828          xen_device_poll(channel);
829  
830          qemu_xen_evtchn_unmask(channel->xeh, port);
831      }
832  }
833  
834  void xen_device_set_event_channel_context(XenDevice *xendev,
835                                            XenEventChannel *channel,
836                                            AioContext *ctx,
837                                            Error **errp)
838  {
839      if (!channel) {
840          error_setg(errp, "bad channel");
841          return;
842      }
843  
844      if (channel->ctx)
845          aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
846                             NULL, NULL, NULL, NULL, NULL);
847  
848      channel->ctx = ctx;
849      if (ctx) {
850          aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
851                             xen_device_event, NULL, xen_device_poll, NULL,
852                             channel);
853      }
854  }
855  
856  XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
857                                                 unsigned int port,
858                                                 XenEventHandler handler,
859                                                 void *opaque, Error **errp)
860  {
861      XenEventChannel *channel = g_new0(XenEventChannel, 1);
862      xenevtchn_port_or_error_t local_port;
863  
864      channel->xeh = qemu_xen_evtchn_open();
865      if (!channel->xeh) {
866          error_setg_errno(errp, errno, "failed xenevtchn_open");
867          goto fail;
868      }
869  
870      local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
871                                              xendev->frontend_id,
872                                              port);
873      if (local_port < 0) {
874          error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
875          goto fail;
876      }
877  
878      channel->local_port = local_port;
879      channel->handler = handler;
880      channel->opaque = opaque;
881  
882      /* Only reason for failure is a NULL channel */
883      xen_device_set_event_channel_context(xendev, channel,
884                                           qemu_get_aio_context(),
885                                           &error_abort);
886  
887      QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
888  
889      return channel;
890  
891  fail:
892      if (channel->xeh) {
893          qemu_xen_evtchn_close(channel->xeh);
894      }
895  
896      g_free(channel);
897  
898      return NULL;
899  }
900  
901  void xen_device_notify_event_channel(XenDevice *xendev,
902                                       XenEventChannel *channel,
903                                       Error **errp)
904  {
905      if (!channel) {
906          error_setg(errp, "bad channel");
907          return;
908      }
909  
910      if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
911          error_setg_errno(errp, errno, "xenevtchn_notify failed");
912      }
913  }
914  
915  void xen_device_unbind_event_channel(XenDevice *xendev,
916                                       XenEventChannel *channel,
917                                       Error **errp)
918  {
919      if (!channel) {
920          error_setg(errp, "bad channel");
921          return;
922      }
923  
924      QLIST_REMOVE(channel, list);
925  
926      if (channel->ctx) {
927          aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
928                             NULL, NULL, NULL, NULL, NULL);
929      }
930  
931      if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
932          error_setg_errno(errp, errno, "xenevtchn_unbind failed");
933      }
934  
935      qemu_xen_evtchn_close(channel->xeh);
936      g_free(channel);
937  }
938  
939  static void xen_device_unrealize(DeviceState *dev)
940  {
941      XenDevice *xendev = XEN_DEVICE(dev);
942      XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
943      const char *type = object_get_typename(OBJECT(xendev));
944      XenEventChannel *channel, *next;
945  
946      if (!xendev->name) {
947          return;
948      }
949  
950      trace_xen_device_unrealize(type, xendev->name);
951  
952      if (xendev->exit.notify) {
953          qemu_remove_exit_notifier(&xendev->exit);
954          xendev->exit.notify = NULL;
955      }
956  
957      if (xendev_class->unrealize) {
958          xendev_class->unrealize(xendev);
959      }
960  
961      /* Make sure all event channels are cleaned up */
962      QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
963          xen_device_unbind_event_channel(xendev, channel, NULL);
964      }
965  
966      xen_device_frontend_destroy(xendev);
967      xen_device_backend_destroy(xendev);
968  
969      if (xendev->xgth) {
970          qemu_xen_gnttab_close(xendev->xgth);
971          xendev->xgth = NULL;
972      }
973  
974      if (xendev->xsh) {
975          qemu_xen_xs_close(xendev->xsh);
976          xendev->xsh = NULL;
977      }
978  
979      g_free(xendev->name);
980      xendev->name = NULL;
981  }
982  
983  static void xen_device_exit(Notifier *n, void *data)
984  {
985      XenDevice *xendev = container_of(n, XenDevice, exit);
986  
987      xen_device_unrealize(DEVICE(xendev));
988  }
989  
990  static void xen_device_realize(DeviceState *dev, Error **errp)
991  {
992      ERRP_GUARD();
993      XenDevice *xendev = XEN_DEVICE(dev);
994      XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
995      XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
996      const char *type = object_get_typename(OBJECT(xendev));
997  
998      if (xendev->frontend_id == DOMID_INVALID) {
999          xendev->frontend_id = xen_domid;
1000      }
1001  
1002      if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1003          error_setg(errp, "invalid frontend-id");
1004          goto unrealize;
1005      }
1006  
1007      if (!xendev_class->get_name) {
1008          error_setg(errp, "get_name method not implemented");
1009          goto unrealize;
1010      }
1011  
1012      xendev->name = xendev_class->get_name(xendev, errp);
1013      if (*errp) {
1014          error_prepend(errp, "failed to get device name: ");
1015          goto unrealize;
1016      }
1017  
1018      trace_xen_device_realize(type, xendev->name);
1019  
1020      xendev->xsh = qemu_xen_xs_open();
1021      if (!xendev->xsh) {
1022          error_setg_errno(errp, errno, "failed xs_open");
1023          goto unrealize;
1024      }
1025  
1026      xendev->xgth = qemu_xen_gnttab_open();
1027      if (!xendev->xgth) {
1028          error_setg_errno(errp, errno, "failed xengnttab_open");
1029          goto unrealize;
1030      }
1031  
1032      xen_device_backend_create(xendev, errp);
1033      if (*errp) {
1034          goto unrealize;
1035      }
1036  
1037      xen_device_frontend_create(xendev, errp);
1038      if (*errp) {
1039          goto unrealize;
1040      }
1041  
1042      xen_device_backend_printf(xendev, "frontend", "%s",
1043                                xendev->frontend_path);
1044      xen_device_backend_printf(xendev, "frontend-id", "%u",
1045                                xendev->frontend_id);
1046      xen_device_backend_printf(xendev, "hotplug-status", "connected");
1047  
1048      xen_device_backend_set_online(xendev, true);
1049      xen_device_backend_set_state(xendev, XenbusStateInitWait);
1050  
1051      if (!xen_device_frontend_exists(xendev)) {
1052          xen_device_frontend_printf(xendev, "backend", "%s",
1053                                     xendev->backend_path);
1054          xen_device_frontend_printf(xendev, "backend-id", "%u",
1055                                     xenbus->backend_id);
1056  
1057          xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1058      }
1059  
1060      if (xendev_class->realize) {
1061          xendev_class->realize(xendev, errp);
1062          if (*errp) {
1063              goto unrealize;
1064          }
1065      }
1066  
1067      xendev->exit.notify = xen_device_exit;
1068      qemu_add_exit_notifier(&xendev->exit);
1069      return;
1070  
1071  unrealize:
1072      xen_device_unrealize(dev);
1073  }
1074  
1075  static Property xen_device_props[] = {
1076      DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1077                         DOMID_INVALID),
1078      DEFINE_PROP_END_OF_LIST()
1079  };
1080  
1081  static void xen_device_class_init(ObjectClass *class, void *data)
1082  {
1083      DeviceClass *dev_class = DEVICE_CLASS(class);
1084  
1085      dev_class->realize = xen_device_realize;
1086      dev_class->unrealize = xen_device_unrealize;
1087      device_class_set_props(dev_class, xen_device_props);
1088      dev_class->bus_type = TYPE_XEN_BUS;
1089  }
1090  
1091  static const TypeInfo xen_device_type_info = {
1092      .name = TYPE_XEN_DEVICE,
1093      .parent = TYPE_DEVICE,
1094      .instance_size = sizeof(XenDevice),
1095      .abstract = true,
1096      .class_size = sizeof(XenDeviceClass),
1097      .class_init = xen_device_class_init,
1098  };
1099  
1100  typedef struct XenBridge {
1101      SysBusDevice busdev;
1102  } XenBridge;
1103  
1104  #define TYPE_XEN_BRIDGE "xen-bridge"
1105  
1106  static const TypeInfo xen_bridge_type_info = {
1107      .name = TYPE_XEN_BRIDGE,
1108      .parent = TYPE_SYS_BUS_DEVICE,
1109      .instance_size = sizeof(XenBridge),
1110  };
1111  
1112  static void xen_register_types(void)
1113  {
1114      type_register_static(&xen_bridge_type_info);
1115      type_register_static(&xen_bus_type_info);
1116      type_register_static(&xen_device_type_info);
1117  }
1118  
1119  type_init(xen_register_types)
1120  
1121  void xen_bus_init(void)
1122  {
1123      DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1124      BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1125  
1126      sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1127      qbus_set_bus_hotplug_handler(bus);
1128  }
1129