xen-all.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (C) 2014 Citrix Systems UK Ltd.
  3. *
  4. * This work is licensed under the terms of the GNU GPL, version 2. See
  5. * the COPYING file in the top-level directory.
  6. *
  7. * Contributions after 2012-01-13 are licensed under the terms of the
  8. * GNU GPL, version 2 or (at your option) any later version.
  9. */
  10. #include "qemu/osdep.h"
  11. #include "qemu/error-report.h"
  12. #include "qemu/module.h"
  13. #include "qapi/error.h"
  14. #include "hw/xen/xen_native.h"
  15. #include "hw/xen/xen-legacy-backend.h"
  16. #include "hw/xen/xen_pt.h"
  17. #include "hw/xen/xen_igd.h"
  18. #include "chardev/char.h"
  19. #include "qemu/accel.h"
  20. #include "system/cpus.h"
  21. #include "system/xen.h"
  22. #include "system/runstate.h"
  23. #include "migration/misc.h"
  24. #include "migration/global_state.h"
  25. #include "hw/boards.h"
  26. bool xen_allowed;
  27. xc_interface *xen_xc;
  28. xenforeignmemory_handle *xen_fmem;
  29. xendevicemodel_handle *xen_dmod;
  30. static void xenstore_record_dm_state(const char *state)
  31. {
  32. char path[50];
  33. snprintf(path, sizeof (path), "device-model/%u/state", xen_domid);
  34. if (!qemu_xen_xs_write(xenstore, XBT_NULL, path, state, strlen(state))) {
  35. error_report("error recording dm state");
  36. exit(1);
  37. }
  38. }
  39. static void xen_change_state_handler(void *opaque, bool running,
  40. RunState state)
  41. {
  42. if (running) {
  43. /* record state running */
  44. xenstore_record_dm_state("running");
  45. }
  46. }
  47. static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp)
  48. {
  49. return xen_igd_gfx_pt_enabled();
  50. }
  51. static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
  52. {
  53. xen_igd_gfx_pt_set(value, errp);
  54. }
  55. static void xen_setup_post(MachineState *ms, AccelState *accel)
  56. {
  57. int rc;
  58. if (xen_domid_restrict) {
  59. rc = xen_restrict(xen_domid);
  60. if (rc < 0) {
  61. perror("xen: failed to restrict");
  62. exit(1);
  63. }
  64. }
  65. }
  66. static int xen_init(MachineState *ms)
  67. {
  68. MachineClass *mc = MACHINE_GET_CLASS(ms);
  69. xen_xc = xc_interface_open(0, 0, 0);
  70. if (xen_xc == NULL) {
  71. xen_pv_printf(NULL, 0, "can't open xen interface\n");
  72. return -1;
  73. }
  74. xen_fmem = xenforeignmemory_open(0, 0);
  75. if (xen_fmem == NULL) {
  76. xen_pv_printf(NULL, 0, "can't open xen fmem interface\n");
  77. xc_interface_close(xen_xc);
  78. return -1;
  79. }
  80. xen_dmod = xendevicemodel_open(0, 0);
  81. if (xen_dmod == NULL) {
  82. xen_pv_printf(NULL, 0, "can't open xen devicemodel interface\n");
  83. xenforeignmemory_close(xen_fmem);
  84. xc_interface_close(xen_xc);
  85. return -1;
  86. }
  87. /*
  88. * The XenStore write would fail when running restricted so don't attempt
  89. * it in that case. Toolstacks should instead use QMP to listen for state
  90. * changes.
  91. */
  92. if (!xen_domid_restrict) {
  93. qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
  94. }
  95. /*
  96. * opt out of system RAM being allocated by generic code
  97. */
  98. mc->default_ram_id = NULL;
  99. xen_mode = XEN_ATTACH;
  100. return 0;
  101. }
  102. static void xen_accel_class_init(ObjectClass *oc, void *data)
  103. {
  104. AccelClass *ac = ACCEL_CLASS(oc);
  105. static GlobalProperty compat[] = {
  106. { "migration", "store-global-state", "off" },
  107. { "migration", "send-configuration", "off" },
  108. { "migration", "send-section-footer", "off" },
  109. };
  110. ac->name = "Xen";
  111. ac->init_machine = xen_init;
  112. ac->setup_post = xen_setup_post;
  113. ac->allowed = &xen_allowed;
  114. ac->compat_props = g_ptr_array_new();
  115. compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
  116. object_class_property_add_bool(oc, "igd-passthru",
  117. xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru);
  118. object_class_property_set_description(oc, "igd-passthru",
  119. "Set on/off to enable/disable igd passthrou");
  120. }
  121. #define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
  122. static const TypeInfo xen_accel_type = {
  123. .name = TYPE_XEN_ACCEL,
  124. .parent = TYPE_ACCEL,
  125. .class_init = xen_accel_class_init,
  126. };
  127. static void xen_accel_ops_class_init(ObjectClass *oc, void *data)
  128. {
  129. AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
  130. ops->create_vcpu_thread = dummy_start_vcpu_thread;
  131. }
  132. static const TypeInfo xen_accel_ops_type = {
  133. .name = ACCEL_OPS_NAME("xen"),
  134. .parent = TYPE_ACCEL_OPS,
  135. .class_init = xen_accel_ops_class_init,
  136. .abstract = true,
  137. };
  138. static void xen_type_init(void)
  139. {
  140. type_register_static(&xen_accel_type);
  141. type_register_static(&xen_accel_ops_type);
  142. }
  143. type_init(xen_type_init);