xen_platform.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. * XEN platform pci device, formerly known as the event channel device
  3. *
  4. * Copyright (c) 2003-2004 Intel Corp.
  5. * Copyright (c) 2006 XenSource
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "qapi/error.h"
  27. #include "hw/ide/pci.h"
  28. #include "hw/pci/pci.h"
  29. #include "migration/vmstate.h"
  30. #include "net/net.h"
  31. #include "trace.h"
  32. #include "system/xen.h"
  33. #include "system/block-backend.h"
  34. #include "qemu/error-report.h"
  35. #include "qemu/module.h"
  36. #include "qom/object.h"
  37. #ifdef CONFIG_XEN
  38. #include "hw/xen/xen_native.h"
  39. #endif
  40. /* The rule is that xen_native.h must come first */
  41. #include "hw/xen/xen.h"
  42. //#define DEBUG_PLATFORM
  43. #ifdef DEBUG_PLATFORM
  44. #define DPRINTF(fmt, ...) do { \
  45. fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
  46. } while (0)
  47. #else
  48. #define DPRINTF(fmt, ...) do { } while (0)
  49. #endif
  50. #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
  51. struct PCIXenPlatformState {
  52. /*< private >*/
  53. PCIDevice parent_obj;
  54. /*< public >*/
  55. MemoryRegion fixed_io;
  56. MemoryRegion bar;
  57. MemoryRegion mmio_bar;
  58. uint8_t flags; /* used only for version_id == 2 */
  59. uint16_t driver_product_version;
  60. /* Log from guest drivers */
  61. char log_buffer[4096];
  62. int log_buffer_off;
  63. };
  64. #define TYPE_XEN_PLATFORM "xen-platform"
  65. OBJECT_DECLARE_SIMPLE_TYPE(PCIXenPlatformState, XEN_PLATFORM)
  66. #define XEN_PLATFORM_IOPORT 0x10
  67. /* Send bytes to syslog */
  68. static void log_writeb(PCIXenPlatformState *s, char val)
  69. {
  70. if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
  71. /* Flush buffer */
  72. s->log_buffer[s->log_buffer_off] = 0;
  73. trace_xen_platform_log(s->log_buffer);
  74. s->log_buffer_off = 0;
  75. } else {
  76. s->log_buffer[s->log_buffer_off++] = val;
  77. }
  78. }
  79. /*
  80. * Unplug device flags.
  81. *
  82. * The logic got a little confused at some point in the past but this is
  83. * what they do now.
  84. *
  85. * bit 0: Unplug all IDE and SCSI disks.
  86. * bit 1: Unplug all NICs.
  87. * bit 2: Unplug IDE disks except primary master. This is overridden if
  88. * bit 0 is also present in the mask.
  89. * bit 3: Unplug all NVMe disks.
  90. *
  91. */
  92. #define _UNPLUG_IDE_SCSI_DISKS 0
  93. #define UNPLUG_IDE_SCSI_DISKS (1u << _UNPLUG_IDE_SCSI_DISKS)
  94. #define _UNPLUG_ALL_NICS 1
  95. #define UNPLUG_ALL_NICS (1u << _UNPLUG_ALL_NICS)
  96. #define _UNPLUG_AUX_IDE_DISKS 2
  97. #define UNPLUG_AUX_IDE_DISKS (1u << _UNPLUG_AUX_IDE_DISKS)
  98. #define _UNPLUG_NVME_DISKS 3
  99. #define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS)
  100. static bool pci_device_is_passthrough(PCIDevice *d)
  101. {
  102. if (!strcmp(d->name, "xen-pci-passthrough")) {
  103. return true;
  104. }
  105. if (xen_mode == XEN_EMULATE && !strcmp(d->name, "vfio-pci")) {
  106. return true;
  107. }
  108. return false;
  109. }
  110. static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
  111. {
  112. /* We have to ignore passthrough devices */
  113. if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
  114. PCI_CLASS_NETWORK_ETHERNET
  115. && !pci_device_is_passthrough(d)) {
  116. object_unparent(OBJECT(d));
  117. }
  118. }
  119. /* Remove the peer of the NIC device. Normally, this would be a tap device. */
  120. static void del_nic_peer(NICState *nic, void *opaque)
  121. {
  122. NetClientState *nc = qemu_get_queue(nic);
  123. ObjectClass *klass = module_object_class_by_name(nc->model);
  124. /* Only delete peers of PCI NICs that we're about to delete */
  125. if (!klass || !object_class_dynamic_cast(klass, TYPE_PCI_DEVICE)) {
  126. return;
  127. }
  128. if (nc->peer)
  129. qemu_del_net_client(nc->peer);
  130. }
  131. static void pci_unplug_nics(PCIBus *bus)
  132. {
  133. qemu_foreach_nic(del_nic_peer, NULL);
  134. pci_for_each_device(bus, 0, unplug_nic, NULL);
  135. }
  136. /*
  137. * The Xen HVM unplug protocol [1] specifies a mechanism to allow guests to
  138. * request unplug of 'aux' disks (which is stated to mean all IDE disks,
  139. * except the primary master).
  140. *
  141. * NOTE: The semantics of what happens if unplug of all disks and 'aux' disks
  142. * is simultaneously requested is not clear. The implementation assumes
  143. * that an 'all' request overrides an 'aux' request.
  144. *
  145. * [1] https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/misc/hvm-emulated-unplug.pandoc
  146. */
  147. struct ide_unplug_state {
  148. bool aux;
  149. int nr_unplugged;
  150. };
  151. static int ide_dev_unplug(DeviceState *dev, void *_st)
  152. {
  153. struct ide_unplug_state *st = _st;
  154. IDEDevice *idedev;
  155. IDEBus *idebus;
  156. BlockBackend *blk;
  157. int unit;
  158. idedev = IDE_DEVICE(object_dynamic_cast(OBJECT(dev), "ide-hd"));
  159. if (!idedev) {
  160. return 0;
  161. }
  162. idebus = IDE_BUS(qdev_get_parent_bus(dev));
  163. unit = (idedev == idebus->slave);
  164. assert(unit || idedev == idebus->master);
  165. if (st->aux && !unit && !strcmp(BUS(idebus)->name, "ide.0")) {
  166. return 0;
  167. }
  168. blk = idebus->ifs[unit].blk;
  169. if (blk) {
  170. blk_drain(blk);
  171. blk_flush(blk);
  172. blk_detach_dev(blk, DEVICE(idedev));
  173. idebus->ifs[unit].blk = NULL;
  174. idedev->conf.blk = NULL;
  175. monitor_remove_blk(blk);
  176. blk_unref(blk);
  177. }
  178. object_unparent(OBJECT(dev));
  179. st->nr_unplugged++;
  180. return 0;
  181. }
  182. static void pci_xen_ide_unplug(PCIDevice *d, bool aux)
  183. {
  184. struct ide_unplug_state st = { aux, 0 };
  185. DeviceState *dev = DEVICE(d);
  186. qdev_walk_children(dev, NULL, NULL, ide_dev_unplug, NULL, &st);
  187. if (st.nr_unplugged) {
  188. pci_device_reset(d);
  189. }
  190. }
  191. static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque)
  192. {
  193. uint32_t flags = *(uint32_t *)opaque;
  194. bool aux = (flags & UNPLUG_AUX_IDE_DISKS) &&
  195. !(flags & UNPLUG_IDE_SCSI_DISKS);
  196. /* We have to ignore passthrough devices */
  197. if (pci_device_is_passthrough(d))
  198. return;
  199. switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) {
  200. case PCI_CLASS_STORAGE_IDE:
  201. case PCI_CLASS_STORAGE_SATA:
  202. pci_xen_ide_unplug(d, aux);
  203. break;
  204. case PCI_CLASS_STORAGE_SCSI:
  205. if (!aux) {
  206. object_unparent(OBJECT(d));
  207. }
  208. break;
  209. case PCI_CLASS_STORAGE_EXPRESS:
  210. if (flags & UNPLUG_NVME_DISKS) {
  211. object_unparent(OBJECT(d));
  212. }
  213. default:
  214. break;
  215. }
  216. }
  217. static void pci_unplug_disks(PCIBus *bus, uint32_t flags)
  218. {
  219. pci_for_each_device(bus, 0, unplug_disks, &flags);
  220. }
  221. static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
  222. {
  223. PCIXenPlatformState *s = opaque;
  224. switch (addr) {
  225. case 0: {
  226. PCIDevice *pci_dev = PCI_DEVICE(s);
  227. /* Unplug devices. See comment above flag definitions */
  228. if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
  229. UNPLUG_NVME_DISKS)) {
  230. DPRINTF("unplug disks\n");
  231. pci_unplug_disks(pci_get_bus(pci_dev), val);
  232. }
  233. if (val & UNPLUG_ALL_NICS) {
  234. DPRINTF("unplug nics\n");
  235. pci_unplug_nics(pci_get_bus(pci_dev));
  236. }
  237. break;
  238. }
  239. case 2:
  240. switch (val) {
  241. case 1:
  242. DPRINTF("Citrix Windows PV drivers loaded in guest\n");
  243. break;
  244. case 0:
  245. DPRINTF("Guest claimed to be running PV product 0?\n");
  246. break;
  247. default:
  248. DPRINTF("Unknown PV product %d loaded in guest\n", val);
  249. break;
  250. }
  251. s->driver_product_version = val;
  252. break;
  253. }
  254. }
  255. static void platform_fixed_ioport_writel(void *opaque, uint32_t addr,
  256. uint32_t val)
  257. {
  258. switch (addr) {
  259. case 0:
  260. /* PV driver version */
  261. break;
  262. }
  263. }
  264. static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
  265. {
  266. PCIXenPlatformState *s = opaque;
  267. switch (addr) {
  268. case 0: /* Platform flags */
  269. if (xen_mode == XEN_EMULATE) {
  270. /* XX: Use i440gx/q35 PAM setup to do this? */
  271. s->flags = val & PFFLAG_ROM_LOCK;
  272. #ifdef CONFIG_XEN
  273. } else {
  274. hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
  275. HVMMEM_ram_ro : HVMMEM_ram_rw;
  276. if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) {
  277. DPRINTF("unable to change ro/rw state of ROM memory area!\n");
  278. } else {
  279. s->flags = val & PFFLAG_ROM_LOCK;
  280. DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n",
  281. (mem_type == HVMMEM_ram_ro ? "ro" : "rw"));
  282. }
  283. #endif
  284. }
  285. break;
  286. case 2:
  287. log_writeb(s, val);
  288. break;
  289. }
  290. }
  291. static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr)
  292. {
  293. switch (addr) {
  294. case 0:
  295. /* Magic value so that you can identify the interface. */
  296. return 0x49d2;
  297. default:
  298. return 0xffff;
  299. }
  300. }
  301. static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
  302. {
  303. PCIXenPlatformState *s = opaque;
  304. switch (addr) {
  305. case 0:
  306. /* Platform flags */
  307. return s->flags;
  308. case 2:
  309. /* Version number */
  310. return 1;
  311. default:
  312. return 0xff;
  313. }
  314. }
  315. static void platform_fixed_ioport_reset(void *opaque)
  316. {
  317. PCIXenPlatformState *s = opaque;
  318. platform_fixed_ioport_writeb(s, 0, 0);
  319. }
  320. static uint64_t platform_fixed_ioport_read(void *opaque,
  321. hwaddr addr,
  322. unsigned size)
  323. {
  324. switch (size) {
  325. case 1:
  326. return platform_fixed_ioport_readb(opaque, addr);
  327. case 2:
  328. return platform_fixed_ioport_readw(opaque, addr);
  329. default:
  330. return -1;
  331. }
  332. }
  333. static void platform_fixed_ioport_write(void *opaque, hwaddr addr,
  334. uint64_t val, unsigned size)
  335. {
  336. switch (size) {
  337. case 1:
  338. platform_fixed_ioport_writeb(opaque, addr, val);
  339. break;
  340. case 2:
  341. platform_fixed_ioport_writew(opaque, addr, val);
  342. break;
  343. case 4:
  344. platform_fixed_ioport_writel(opaque, addr, val);
  345. break;
  346. }
  347. }
  348. static const MemoryRegionOps platform_fixed_io_ops = {
  349. .read = platform_fixed_ioport_read,
  350. .write = platform_fixed_ioport_write,
  351. .valid = {
  352. .unaligned = true,
  353. },
  354. .impl = {
  355. .min_access_size = 1,
  356. .max_access_size = 4,
  357. .unaligned = true,
  358. },
  359. .endianness = DEVICE_LITTLE_ENDIAN,
  360. };
  361. static void platform_fixed_ioport_init(PCIXenPlatformState* s)
  362. {
  363. memory_region_init_io(&s->fixed_io, OBJECT(s), &platform_fixed_io_ops, s,
  364. "xen-fixed", 16);
  365. memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT,
  366. &s->fixed_io);
  367. }
  368. /* Xen Platform PCI Device */
  369. static uint64_t xen_platform_ioport_readb(void *opaque, hwaddr addr,
  370. unsigned int size)
  371. {
  372. if (addr == 0) {
  373. return platform_fixed_ioport_readb(opaque, 0);
  374. } else {
  375. return ~0u;
  376. }
  377. }
  378. static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
  379. uint64_t val, unsigned int size)
  380. {
  381. PCIXenPlatformState *s = opaque;
  382. PCIDevice *pci_dev = PCI_DEVICE(s);
  383. switch (addr) {
  384. case 0: /* Platform flags */
  385. platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
  386. break;
  387. case 4:
  388. if (val == 1) {
  389. /*
  390. * SUSE unplug for Xenlinux
  391. * xen-kmp used this since xen-3.0.4, instead the official protocol
  392. * from xen-3.3+ It did an unconditional "outl(1, (ioaddr + 4));"
  393. * Pre VMDP 1.7 used 4 and 8 depending on how VMDP was configured.
  394. * If VMDP was to control both disk and LAN it would use 4.
  395. * If it controlled just disk or just LAN, it would use 8 below.
  396. */
  397. pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
  398. pci_unplug_nics(pci_get_bus(pci_dev));
  399. }
  400. break;
  401. case 8:
  402. switch (val) {
  403. case 1:
  404. pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
  405. break;
  406. case 2:
  407. pci_unplug_nics(pci_get_bus(pci_dev));
  408. break;
  409. default:
  410. log_writeb(s, (uint32_t)val);
  411. break;
  412. }
  413. break;
  414. default:
  415. break;
  416. }
  417. }
  418. static const MemoryRegionOps xen_pci_io_ops = {
  419. .read = xen_platform_ioport_readb,
  420. .write = xen_platform_ioport_writeb,
  421. .impl.min_access_size = 1,
  422. .impl.max_access_size = 1,
  423. };
  424. static void platform_ioport_bar_setup(PCIXenPlatformState *d)
  425. {
  426. memory_region_init_io(&d->bar, OBJECT(d), &xen_pci_io_ops, d,
  427. "xen-pci", 0x100);
  428. }
  429. static uint64_t platform_mmio_read(void *opaque, hwaddr addr,
  430. unsigned size)
  431. {
  432. DPRINTF("Warning: attempted read from physical address "
  433. "0x" HWADDR_FMT_plx " in xen platform mmio space\n", addr);
  434. return 0;
  435. }
  436. static void platform_mmio_write(void *opaque, hwaddr addr,
  437. uint64_t val, unsigned size)
  438. {
  439. DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical "
  440. "address 0x" HWADDR_FMT_plx " in xen platform mmio space\n",
  441. val, addr);
  442. }
  443. static const MemoryRegionOps platform_mmio_handler = {
  444. .read = &platform_mmio_read,
  445. .write = &platform_mmio_write,
  446. .endianness = DEVICE_LITTLE_ENDIAN,
  447. };
  448. static void platform_mmio_setup(PCIXenPlatformState *d)
  449. {
  450. memory_region_init_io(&d->mmio_bar, OBJECT(d), &platform_mmio_handler, d,
  451. "xen-mmio", 0x1000000);
  452. }
  453. static int xen_platform_post_load(void *opaque, int version_id)
  454. {
  455. PCIXenPlatformState *s = opaque;
  456. platform_fixed_ioport_writeb(s, 0, s->flags);
  457. return 0;
  458. }
  459. static const VMStateDescription vmstate_xen_platform = {
  460. .name = "platform",
  461. .version_id = 4,
  462. .minimum_version_id = 4,
  463. .post_load = xen_platform_post_load,
  464. .fields = (const VMStateField[]) {
  465. VMSTATE_PCI_DEVICE(parent_obj, PCIXenPlatformState),
  466. VMSTATE_UINT8(flags, PCIXenPlatformState),
  467. VMSTATE_END_OF_LIST()
  468. }
  469. };
  470. static void xen_platform_realize(PCIDevice *dev, Error **errp)
  471. {
  472. PCIXenPlatformState *d = XEN_PLATFORM(dev);
  473. uint8_t *pci_conf;
  474. /* Device will crash on reset if xen is not initialized */
  475. if (xen_mode == XEN_DISABLED) {
  476. error_setg(errp, "xen-platform device requires a Xen guest");
  477. return;
  478. }
  479. pci_conf = dev->config;
  480. pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
  481. pci_config_set_prog_interface(pci_conf, 0);
  482. pci_conf[PCI_INTERRUPT_PIN] = 1;
  483. platform_ioport_bar_setup(d);
  484. pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
  485. /* reserve 16MB mmio address for share memory*/
  486. platform_mmio_setup(d);
  487. pci_register_bar(dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
  488. &d->mmio_bar);
  489. platform_fixed_ioport_init(d);
  490. }
  491. static void platform_reset(DeviceState *dev)
  492. {
  493. PCIXenPlatformState *s = XEN_PLATFORM(dev);
  494. platform_fixed_ioport_reset(s);
  495. }
  496. static void xen_platform_class_init(ObjectClass *klass, void *data)
  497. {
  498. DeviceClass *dc = DEVICE_CLASS(klass);
  499. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  500. k->realize = xen_platform_realize;
  501. k->vendor_id = PCI_VENDOR_ID_XEN;
  502. k->device_id = PCI_DEVICE_ID_XEN_PLATFORM;
  503. k->class_id = PCI_CLASS_OTHERS << 8 | 0x80;
  504. k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;
  505. k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;
  506. k->revision = 1;
  507. set_bit(DEVICE_CATEGORY_MISC, dc->categories);
  508. dc->desc = "XEN platform pci device";
  509. device_class_set_legacy_reset(dc, platform_reset);
  510. dc->vmsd = &vmstate_xen_platform;
  511. }
  512. static const TypeInfo xen_platform_info = {
  513. .name = TYPE_XEN_PLATFORM,
  514. .parent = TYPE_PCI_DEVICE,
  515. .instance_size = sizeof(PCIXenPlatformState),
  516. .class_init = xen_platform_class_init,
  517. .interfaces = (InterfaceInfo[]) {
  518. { INTERFACE_CONVENTIONAL_PCI_DEVICE },
  519. { },
  520. },
  521. };
  522. static void xen_platform_register_types(void)
  523. {
  524. type_register_static(&xen_platform_info);
  525. }
  526. type_init(xen_platform_register_types)