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 26 #include "qemu/osdep.h" 27 #include "qapi/error.h" 28 #include "hw/ide.h" 29 #include "hw/pci/pci.h" 30 #include "hw/irq.h" 31 #include "hw/xen/xen_common.h" 32 #include "migration/vmstate.h" 33 #include "hw/xen/xen-legacy-backend.h" 34 #include "trace.h" 35 #include "exec/address-spaces.h" 36 #include "sysemu/xen.h" 37 #include "sysemu/block-backend.h" 38 #include "qemu/error-report.h" 39 #include "qemu/module.h" 40 41 #include <xenguest.h> 42 #include "qom/object.h" 43 44 //#define DEBUG_PLATFORM 45 46 #ifdef DEBUG_PLATFORM 47 #define DPRINTF(fmt, ...) do { \ 48 fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \ 49 } while (0) 50 #else 51 #define DPRINTF(fmt, ...) do { } while (0) 52 #endif 53 54 #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */ 55 56 struct PCIXenPlatformState { 57 /*< private >*/ 58 PCIDevice parent_obj; 59 /*< public >*/ 60 61 MemoryRegion fixed_io; 62 MemoryRegion bar; 63 MemoryRegion mmio_bar; 64 uint8_t flags; /* used only for version_id == 2 */ 65 int drivers_blacklisted; 66 uint16_t driver_product_version; 67 68 /* Log from guest drivers */ 69 char log_buffer[4096]; 70 int log_buffer_off; 71 }; 72 typedef struct PCIXenPlatformState PCIXenPlatformState; 73 74 #define TYPE_XEN_PLATFORM "xen-platform" 75 DECLARE_INSTANCE_CHECKER(PCIXenPlatformState, XEN_PLATFORM, 76 TYPE_XEN_PLATFORM) 77 78 #define XEN_PLATFORM_IOPORT 0x10 79 80 /* Send bytes to syslog */ 81 static void log_writeb(PCIXenPlatformState *s, char val) 82 { 83 if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) { 84 /* Flush buffer */ 85 s->log_buffer[s->log_buffer_off] = 0; 86 trace_xen_platform_log(s->log_buffer); 87 s->log_buffer_off = 0; 88 } else { 89 s->log_buffer[s->log_buffer_off++] = val; 90 } 91 } 92 93 /* 94 * Unplug device flags. 95 * 96 * The logic got a little confused at some point in the past but this is 97 * what they do now. 98 * 99 * bit 0: Unplug all IDE and SCSI disks. 100 * bit 1: Unplug all NICs. 101 * bit 2: Unplug IDE disks except primary master. This is overridden if 102 * bit 0 is also present in the mask. 103 * bit 3: Unplug all NVMe disks. 104 * 105 */ 106 #define _UNPLUG_IDE_SCSI_DISKS 0 107 #define UNPLUG_IDE_SCSI_DISKS (1u << _UNPLUG_IDE_SCSI_DISKS) 108 109 #define _UNPLUG_ALL_NICS 1 110 #define UNPLUG_ALL_NICS (1u << _UNPLUG_ALL_NICS) 111 112 #define _UNPLUG_AUX_IDE_DISKS 2 113 #define UNPLUG_AUX_IDE_DISKS (1u << _UNPLUG_AUX_IDE_DISKS) 114 115 #define _UNPLUG_NVME_DISKS 3 116 #define UNPLUG_NVME_DISKS (1u << _UNPLUG_NVME_DISKS) 117 118 static void unplug_nic(PCIBus *b, PCIDevice *d, void *o) 119 { 120 /* We have to ignore passthrough devices */ 121 if (pci_get_word(d->config + PCI_CLASS_DEVICE) == 122 PCI_CLASS_NETWORK_ETHERNET 123 && strcmp(d->name, "xen-pci-passthrough") != 0) { 124 object_unparent(OBJECT(d)); 125 } 126 } 127 128 /* Remove the peer of the NIC device. Normally, this would be a tap device. */ 129 static void del_nic_peer(NICState *nic, void *opaque) 130 { 131 NetClientState *nc; 132 133 nc = qemu_get_queue(nic); 134 if (nc->peer) 135 qemu_del_net_client(nc->peer); 136 } 137 138 static void pci_unplug_nics(PCIBus *bus) 139 { 140 qemu_foreach_nic(del_nic_peer, NULL); 141 pci_for_each_device(bus, 0, unplug_nic, NULL); 142 } 143 144 static void unplug_disks(PCIBus *b, PCIDevice *d, void *opaque) 145 { 146 uint32_t flags = *(uint32_t *)opaque; 147 bool aux = (flags & UNPLUG_AUX_IDE_DISKS) && 148 !(flags & UNPLUG_IDE_SCSI_DISKS); 149 150 /* We have to ignore passthrough devices */ 151 if (!strcmp(d->name, "xen-pci-passthrough")) { 152 return; 153 } 154 155 switch (pci_get_word(d->config + PCI_CLASS_DEVICE)) { 156 case PCI_CLASS_STORAGE_IDE: 157 pci_piix3_xen_ide_unplug(DEVICE(d), aux); 158 break; 159 160 case PCI_CLASS_STORAGE_SCSI: 161 if (!aux) { 162 object_unparent(OBJECT(d)); 163 } 164 break; 165 166 case PCI_CLASS_STORAGE_EXPRESS: 167 if (flags & UNPLUG_NVME_DISKS) { 168 object_unparent(OBJECT(d)); 169 } 170 171 default: 172 break; 173 } 174 } 175 176 static void pci_unplug_disks(PCIBus *bus, uint32_t flags) 177 { 178 pci_for_each_device(bus, 0, unplug_disks, &flags); 179 } 180 181 static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val) 182 { 183 PCIXenPlatformState *s = opaque; 184 185 switch (addr) { 186 case 0: { 187 PCIDevice *pci_dev = PCI_DEVICE(s); 188 /* Unplug devices. See comment above flag definitions */ 189 if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS | 190 UNPLUG_NVME_DISKS)) { 191 DPRINTF("unplug disks\n"); 192 pci_unplug_disks(pci_get_bus(pci_dev), val); 193 } 194 if (val & UNPLUG_ALL_NICS) { 195 DPRINTF("unplug nics\n"); 196 pci_unplug_nics(pci_get_bus(pci_dev)); 197 } 198 break; 199 } 200 case 2: 201 switch (val) { 202 case 1: 203 DPRINTF("Citrix Windows PV drivers loaded in guest\n"); 204 break; 205 case 0: 206 DPRINTF("Guest claimed to be running PV product 0?\n"); 207 break; 208 default: 209 DPRINTF("Unknown PV product %d loaded in guest\n", val); 210 break; 211 } 212 s->driver_product_version = val; 213 break; 214 } 215 } 216 217 static void platform_fixed_ioport_writel(void *opaque, uint32_t addr, 218 uint32_t val) 219 { 220 switch (addr) { 221 case 0: 222 /* PV driver version */ 223 break; 224 } 225 } 226 227 static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) 228 { 229 PCIXenPlatformState *s = opaque; 230 231 switch (addr) { 232 case 0: /* Platform flags */ { 233 hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ? 234 HVMMEM_ram_ro : HVMMEM_ram_rw; 235 if (xen_set_mem_type(xen_domid, mem_type, 0xc0, 0x40)) { 236 DPRINTF("unable to change ro/rw state of ROM memory area!\n"); 237 } else { 238 s->flags = val & PFFLAG_ROM_LOCK; 239 DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n", 240 (mem_type == HVMMEM_ram_ro ? "ro":"rw")); 241 } 242 break; 243 } 244 case 2: 245 log_writeb(s, val); 246 break; 247 } 248 } 249 250 static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr) 251 { 252 PCIXenPlatformState *s = opaque; 253 254 switch (addr) { 255 case 0: 256 if (s->drivers_blacklisted) { 257 /* The drivers will recognise this magic number and refuse 258 * to do anything. */ 259 return 0xd249; 260 } else { 261 /* Magic value so that you can identify the interface. */ 262 return 0x49d2; 263 } 264 default: 265 return 0xffff; 266 } 267 } 268 269 static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr) 270 { 271 PCIXenPlatformState *s = opaque; 272 273 switch (addr) { 274 case 0: 275 /* Platform flags */ 276 return s->flags; 277 case 2: 278 /* Version number */ 279 return 1; 280 default: 281 return 0xff; 282 } 283 } 284 285 static void platform_fixed_ioport_reset(void *opaque) 286 { 287 PCIXenPlatformState *s = opaque; 288 289 platform_fixed_ioport_writeb(s, 0, 0); 290 } 291 292 static uint64_t platform_fixed_ioport_read(void *opaque, 293 hwaddr addr, 294 unsigned size) 295 { 296 switch (size) { 297 case 1: 298 return platform_fixed_ioport_readb(opaque, addr); 299 case 2: 300 return platform_fixed_ioport_readw(opaque, addr); 301 default: 302 return -1; 303 } 304 } 305 306 static void platform_fixed_ioport_write(void *opaque, hwaddr addr, 307 308 uint64_t val, unsigned size) 309 { 310 switch (size) { 311 case 1: 312 platform_fixed_ioport_writeb(opaque, addr, val); 313 break; 314 case 2: 315 platform_fixed_ioport_writew(opaque, addr, val); 316 break; 317 case 4: 318 platform_fixed_ioport_writel(opaque, addr, val); 319 break; 320 } 321 } 322 323 324 static const MemoryRegionOps platform_fixed_io_ops = { 325 .read = platform_fixed_ioport_read, 326 .write = platform_fixed_ioport_write, 327 .valid = { 328 .unaligned = true, 329 }, 330 .impl = { 331 .min_access_size = 1, 332 .max_access_size = 4, 333 .unaligned = true, 334 }, 335 .endianness = DEVICE_LITTLE_ENDIAN, 336 }; 337 338 static void platform_fixed_ioport_init(PCIXenPlatformState* s) 339 { 340 memory_region_init_io(&s->fixed_io, OBJECT(s), &platform_fixed_io_ops, s, 341 "xen-fixed", 16); 342 memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT, 343 &s->fixed_io); 344 } 345 346 /* Xen Platform PCI Device */ 347 348 static uint64_t xen_platform_ioport_readb(void *opaque, hwaddr addr, 349 unsigned int size) 350 { 351 if (addr == 0) { 352 return platform_fixed_ioport_readb(opaque, 0); 353 } else { 354 return ~0u; 355 } 356 } 357 358 static void xen_platform_ioport_writeb(void *opaque, hwaddr addr, 359 uint64_t val, unsigned int size) 360 { 361 PCIXenPlatformState *s = opaque; 362 PCIDevice *pci_dev = PCI_DEVICE(s); 363 364 switch (addr) { 365 case 0: /* Platform flags */ 366 platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val); 367 break; 368 case 4: 369 if (val == 1) { 370 /* 371 * SUSE unplug for Xenlinux 372 * xen-kmp used this since xen-3.0.4, instead the official protocol 373 * from xen-3.3+ It did an unconditional "outl(1, (ioaddr + 4));" 374 * Pre VMDP 1.7 used 4 and 8 depending on how VMDP was configured. 375 * If VMDP was to control both disk and LAN it would use 4. 376 * If it controlled just disk or just LAN, it would use 8 below. 377 */ 378 pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS); 379 pci_unplug_nics(pci_get_bus(pci_dev)); 380 } 381 break; 382 case 8: 383 switch (val) { 384 case 1: 385 pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS); 386 break; 387 case 2: 388 pci_unplug_nics(pci_get_bus(pci_dev)); 389 break; 390 default: 391 log_writeb(s, (uint32_t)val); 392 break; 393 } 394 break; 395 default: 396 break; 397 } 398 } 399 400 static const MemoryRegionOps xen_pci_io_ops = { 401 .read = xen_platform_ioport_readb, 402 .write = xen_platform_ioport_writeb, 403 .impl.min_access_size = 1, 404 .impl.max_access_size = 1, 405 }; 406 407 static void platform_ioport_bar_setup(PCIXenPlatformState *d) 408 { 409 memory_region_init_io(&d->bar, OBJECT(d), &xen_pci_io_ops, d, 410 "xen-pci", 0x100); 411 } 412 413 static uint64_t platform_mmio_read(void *opaque, hwaddr addr, 414 unsigned size) 415 { 416 DPRINTF("Warning: attempted read from physical address " 417 "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr); 418 419 return 0; 420 } 421 422 static void platform_mmio_write(void *opaque, hwaddr addr, 423 uint64_t val, unsigned size) 424 { 425 DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical " 426 "address 0x" TARGET_FMT_plx " in xen platform mmio space\n", 427 val, addr); 428 } 429 430 static const MemoryRegionOps platform_mmio_handler = { 431 .read = &platform_mmio_read, 432 .write = &platform_mmio_write, 433 .endianness = DEVICE_NATIVE_ENDIAN, 434 }; 435 436 static void platform_mmio_setup(PCIXenPlatformState *d) 437 { 438 memory_region_init_io(&d->mmio_bar, OBJECT(d), &platform_mmio_handler, d, 439 "xen-mmio", 0x1000000); 440 } 441 442 static int xen_platform_post_load(void *opaque, int version_id) 443 { 444 PCIXenPlatformState *s = opaque; 445 446 platform_fixed_ioport_writeb(s, 0, s->flags); 447 448 return 0; 449 } 450 451 static const VMStateDescription vmstate_xen_platform = { 452 .name = "platform", 453 .version_id = 4, 454 .minimum_version_id = 4, 455 .post_load = xen_platform_post_load, 456 .fields = (VMStateField[]) { 457 VMSTATE_PCI_DEVICE(parent_obj, PCIXenPlatformState), 458 VMSTATE_UINT8(flags, PCIXenPlatformState), 459 VMSTATE_END_OF_LIST() 460 } 461 }; 462 463 static void xen_platform_realize(PCIDevice *dev, Error **errp) 464 { 465 PCIXenPlatformState *d = XEN_PLATFORM(dev); 466 uint8_t *pci_conf; 467 468 /* Device will crash on reset if xen is not initialized */ 469 if (!xen_enabled()) { 470 error_setg(errp, "xen-platform device requires the Xen accelerator"); 471 return; 472 } 473 474 pci_conf = dev->config; 475 476 pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); 477 478 pci_config_set_prog_interface(pci_conf, 0); 479 480 pci_conf[PCI_INTERRUPT_PIN] = 1; 481 482 platform_ioport_bar_setup(d); 483 pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar); 484 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 490 platform_fixed_ioport_init(d); 491 } 492 493 static void platform_reset(DeviceState *dev) 494 { 495 PCIXenPlatformState *s = XEN_PLATFORM(dev); 496 497 platform_fixed_ioport_reset(s); 498 } 499 500 static void xen_platform_class_init(ObjectClass *klass, void *data) 501 { 502 DeviceClass *dc = DEVICE_CLASS(klass); 503 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 504 505 k->realize = xen_platform_realize; 506 k->vendor_id = PCI_VENDOR_ID_XEN; 507 k->device_id = PCI_DEVICE_ID_XEN_PLATFORM; 508 k->class_id = PCI_CLASS_OTHERS << 8 | 0x80; 509 k->subsystem_vendor_id = PCI_VENDOR_ID_XEN; 510 k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM; 511 k->revision = 1; 512 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 513 dc->desc = "XEN platform pci device"; 514 dc->reset = platform_reset; 515 dc->vmsd = &vmstate_xen_platform; 516 } 517 518 static const TypeInfo xen_platform_info = { 519 .name = TYPE_XEN_PLATFORM, 520 .parent = TYPE_PCI_DEVICE, 521 .instance_size = sizeof(PCIXenPlatformState), 522 .class_init = xen_platform_class_init, 523 .interfaces = (InterfaceInfo[]) { 524 { INTERFACE_CONVENTIONAL_PCI_DEVICE }, 525 { }, 526 }, 527 }; 528 529 static void xen_platform_register_types(void) 530 { 531 type_register_static(&xen_platform_info); 532 } 533 534 type_init(xen_platform_register_types) 535