xen-bus.c 38 KB

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