pci-hotplug.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * QEMU PCI hotplug support
  3. *
  4. * Copyright (c) 2004 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "hw/hw.h"
  25. #include "hw/boards.h"
  26. #include "hw/pci/pci.h"
  27. #include "net/net.h"
  28. #include "hw/pc.h"
  29. #include "monitor/monitor.h"
  30. #include "hw/scsi.h"
  31. #include "hw/virtio-blk.h"
  32. #include "qemu/config-file.h"
  33. #include "sysemu/blockdev.h"
  34. #include "qapi/error.h"
  35. #if defined(TARGET_I386)
  36. static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
  37. const char *devaddr,
  38. const char *opts_str)
  39. {
  40. Error *local_err = NULL;
  41. QemuOpts *opts;
  42. PCIBus *bus;
  43. int ret, devfn;
  44. bus = pci_get_bus_devfn(&devfn, devaddr);
  45. if (!bus) {
  46. monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
  47. return NULL;
  48. }
  49. if (!((BusState*)bus)->allow_hotplug) {
  50. monitor_printf(mon, "PCI bus doesn't support hotplug\n");
  51. return NULL;
  52. }
  53. opts = qemu_opts_parse(qemu_find_opts("net"), opts_str ? opts_str : "", 0);
  54. if (!opts) {
  55. return NULL;
  56. }
  57. qemu_opt_set(opts, "type", "nic");
  58. ret = net_client_init(opts, 0, &local_err);
  59. if (error_is_set(&local_err)) {
  60. qerror_report_err(local_err);
  61. error_free(local_err);
  62. return NULL;
  63. }
  64. if (nd_table[ret].devaddr) {
  65. monitor_printf(mon, "Parameter addr not supported\n");
  66. return NULL;
  67. }
  68. return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
  69. }
  70. static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
  71. DriveInfo *dinfo, int printinfo)
  72. {
  73. SCSIBus *scsibus;
  74. SCSIDevice *scsidev;
  75. scsibus = (SCSIBus *)
  76. object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)),
  77. TYPE_SCSI_BUS);
  78. if (!scsibus) {
  79. error_report("Device is not a SCSI adapter");
  80. return -1;
  81. }
  82. /*
  83. * drive_init() tries to find a default for dinfo->unit. Doesn't
  84. * work at all for hotplug though as we assign the device to a
  85. * specific bus instead of the first bus with spare scsi ids.
  86. *
  87. * Ditch the calculated value and reload from option string (if
  88. * specified).
  89. */
  90. dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
  91. dinfo->bus = scsibus->busnr;
  92. scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit,
  93. false, -1);
  94. if (!scsidev) {
  95. return -1;
  96. }
  97. dinfo->unit = scsidev->id;
  98. if (printinfo)
  99. monitor_printf(mon, "OK bus %d, unit %d\n",
  100. scsibus->busnr, scsidev->id);
  101. return 0;
  102. }
  103. int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo)
  104. {
  105. int dom, pci_bus;
  106. unsigned slot;
  107. PCIDevice *dev;
  108. const char *pci_addr = qdict_get_str(qdict, "pci_addr");
  109. switch (dinfo->type) {
  110. case IF_SCSI:
  111. if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
  112. goto err;
  113. }
  114. dev = pci_find_device(pci_find_root_bus(dom), pci_bus,
  115. PCI_DEVFN(slot, 0));
  116. if (!dev) {
  117. monitor_printf(mon, "no pci device with address %s\n", pci_addr);
  118. goto err;
  119. }
  120. if (scsi_hot_add(mon, &dev->qdev, dinfo, 1) != 0) {
  121. goto err;
  122. }
  123. break;
  124. default:
  125. monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
  126. goto err;
  127. }
  128. return 0;
  129. err:
  130. return -1;
  131. }
  132. static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
  133. const char *devaddr,
  134. const char *opts)
  135. {
  136. PCIDevice *dev;
  137. DriveInfo *dinfo = NULL;
  138. int type = -1;
  139. char buf[128];
  140. PCIBus *bus;
  141. int devfn;
  142. if (get_param_value(buf, sizeof(buf), "if", opts)) {
  143. if (!strcmp(buf, "scsi"))
  144. type = IF_SCSI;
  145. else if (!strcmp(buf, "virtio")) {
  146. type = IF_VIRTIO;
  147. } else {
  148. monitor_printf(mon, "type %s not a hotpluggable PCI device.\n", buf);
  149. return NULL;
  150. }
  151. } else {
  152. monitor_printf(mon, "no if= specified\n");
  153. return NULL;
  154. }
  155. if (get_param_value(buf, sizeof(buf), "file", opts)) {
  156. dinfo = add_init_drive(opts);
  157. if (!dinfo)
  158. return NULL;
  159. if (dinfo->devaddr) {
  160. monitor_printf(mon, "Parameter addr not supported\n");
  161. return NULL;
  162. }
  163. } else {
  164. dinfo = NULL;
  165. }
  166. bus = pci_get_bus_devfn(&devfn, devaddr);
  167. if (!bus) {
  168. monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
  169. return NULL;
  170. }
  171. if (!((BusState*)bus)->allow_hotplug) {
  172. monitor_printf(mon, "PCI bus doesn't support hotplug\n");
  173. return NULL;
  174. }
  175. switch (type) {
  176. case IF_SCSI:
  177. dev = pci_create(bus, devfn, "lsi53c895a");
  178. if (qdev_init(&dev->qdev) < 0)
  179. dev = NULL;
  180. if (dev && dinfo) {
  181. if (scsi_hot_add(mon, &dev->qdev, dinfo, 0) != 0) {
  182. qdev_unplug(&dev->qdev, NULL);
  183. dev = NULL;
  184. }
  185. }
  186. break;
  187. case IF_VIRTIO:
  188. if (!dinfo) {
  189. monitor_printf(mon, "virtio requires a backing file/device.\n");
  190. return NULL;
  191. }
  192. dev = pci_create(bus, devfn, "virtio-blk-pci");
  193. if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) {
  194. qdev_free(&dev->qdev);
  195. dev = NULL;
  196. break;
  197. }
  198. if (qdev_init(&dev->qdev) < 0)
  199. dev = NULL;
  200. break;
  201. default:
  202. dev = NULL;
  203. }
  204. return dev;
  205. }
  206. void pci_device_hot_add(Monitor *mon, const QDict *qdict)
  207. {
  208. PCIDevice *dev = NULL;
  209. const char *pci_addr = qdict_get_str(qdict, "pci_addr");
  210. const char *type = qdict_get_str(qdict, "type");
  211. const char *opts = qdict_get_try_str(qdict, "opts");
  212. /* strip legacy tag */
  213. if (!strncmp(pci_addr, "pci_addr=", 9)) {
  214. pci_addr += 9;
  215. }
  216. if (!opts) {
  217. opts = "";
  218. }
  219. if (!strcmp(pci_addr, "auto"))
  220. pci_addr = NULL;
  221. if (strcmp(type, "nic") == 0) {
  222. dev = qemu_pci_hot_add_nic(mon, pci_addr, opts);
  223. } else if (strcmp(type, "storage") == 0) {
  224. dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
  225. } else {
  226. monitor_printf(mon, "invalid type: %s\n", type);
  227. }
  228. if (dev) {
  229. monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n",
  230. pci_find_domain(dev->bus),
  231. pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
  232. PCI_FUNC(dev->devfn));
  233. } else
  234. monitor_printf(mon, "failed to add %s\n", opts);
  235. }
  236. #endif
  237. static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
  238. {
  239. PCIDevice *d;
  240. int dom, bus;
  241. unsigned slot;
  242. Error *local_err = NULL;
  243. if (pci_read_devaddr(mon, pci_addr, &dom, &bus, &slot)) {
  244. return -1;
  245. }
  246. d = pci_find_device(pci_find_root_bus(dom), bus, PCI_DEVFN(slot, 0));
  247. if (!d) {
  248. monitor_printf(mon, "slot %d empty\n", slot);
  249. return -1;
  250. }
  251. qdev_unplug(&d->qdev, &local_err);
  252. if (error_is_set(&local_err)) {
  253. monitor_printf(mon, "%s\n", error_get_pretty(local_err));
  254. error_free(local_err);
  255. return -1;
  256. }
  257. return 0;
  258. }
  259. void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict)
  260. {
  261. pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));
  262. }