1 /* 2 * Copyright (c) 2007, Neocleus Corporation. 3 * Copyright (c) 2007, Intel Corporation. 4 * 5 * This work is licensed under the terms of the GNU GPL, version 2. See 6 * the COPYING file in the top-level directory. 7 * 8 * Alex Novik <alex@neocleus.com> 9 * Allen Kay <allen.m.kay@intel.com> 10 * Guy Zana <guy@neocleus.com> 11 * 12 * This file implements direct PCI assignment to a HVM guest 13 */ 14 15 /* 16 * Interrupt Disable policy: 17 * 18 * INTx interrupt: 19 * Initialize(register_real_device) 20 * Map INTx(xc_physdev_map_pirq): 21 * <fail> 22 * - Set real Interrupt Disable bit to '1'. 23 * - Set machine_irq and assigned_device->machine_irq to '0'. 24 * * Don't bind INTx. 25 * 26 * Bind INTx(xc_domain_bind_pt_pci_irq): 27 * <fail> 28 * - Set real Interrupt Disable bit to '1'. 29 * - Unmap INTx. 30 * - Decrement xen_pt_mapped_machine_irq[machine_irq] 31 * - Set assigned_device->machine_irq to '0'. 32 * 33 * Write to Interrupt Disable bit by guest software(xen_pt_cmd_reg_write) 34 * Write '0' 35 * - Set real bit to '0' if assigned_device->machine_irq isn't '0'. 36 * 37 * Write '1' 38 * - Set real bit to '1'. 39 * 40 * MSI interrupt: 41 * Initialize MSI register(xen_pt_msi_setup, xen_pt_msi_update) 42 * Bind MSI(xc_domain_update_msi_irq) 43 * <fail> 44 * - Unmap MSI. 45 * - Set dev->msi->pirq to '-1'. 46 * 47 * MSI-X interrupt: 48 * Initialize MSI-X register(xen_pt_msix_update_one) 49 * Bind MSI-X(xc_domain_update_msi_irq) 50 * <fail> 51 * - Unmap MSI-X. 52 * - Set entry->pirq to '-1'. 53 */ 54 55 #include <sys/ioctl.h> 56 57 #include "hw/pci/pci.h" 58 #include "hw/xen/xen.h" 59 #include "hw/i386/pc.h" 60 #include "hw/xen/xen_backend.h" 61 #include "xen_pt.h" 62 #include "qemu/range.h" 63 #include "exec/address-spaces.h" 64 65 #define XEN_PT_NR_IRQS (256) 66 static uint8_t xen_pt_mapped_machine_irq[XEN_PT_NR_IRQS] = {0}; 67 68 void xen_pt_log(const PCIDevice *d, const char *f, ...) 69 { 70 va_list ap; 71 72 va_start(ap, f); 73 if (d) { 74 fprintf(stderr, "[%02x:%02x.%d] ", pci_bus_num(d->bus), 75 PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); 76 } 77 vfprintf(stderr, f, ap); 78 va_end(ap); 79 } 80 81 /* Config Space */ 82 83 static int xen_pt_pci_config_access_check(PCIDevice *d, uint32_t addr, int len) 84 { 85 /* check offset range */ 86 if (addr >= 0xFF) { 87 XEN_PT_ERR(d, "Failed to access register with offset exceeding 0xFF. " 88 "(addr: 0x%02x, len: %d)\n", addr, len); 89 return -1; 90 } 91 92 /* check read size */ 93 if ((len != 1) && (len != 2) && (len != 4)) { 94 XEN_PT_ERR(d, "Failed to access register with invalid access length. " 95 "(addr: 0x%02x, len: %d)\n", addr, len); 96 return -1; 97 } 98 99 /* check offset alignment */ 100 if (addr & (len - 1)) { 101 XEN_PT_ERR(d, "Failed to access register with invalid access size " 102 "alignment. (addr: 0x%02x, len: %d)\n", addr, len); 103 return -1; 104 } 105 106 return 0; 107 } 108 109 int xen_pt_bar_offset_to_index(uint32_t offset) 110 { 111 int index = 0; 112 113 /* check Exp ROM BAR */ 114 if (offset == PCI_ROM_ADDRESS) { 115 return PCI_ROM_SLOT; 116 } 117 118 /* calculate BAR index */ 119 index = (offset - PCI_BASE_ADDRESS_0) >> 2; 120 if (index >= PCI_NUM_REGIONS) { 121 return -1; 122 } 123 124 return index; 125 } 126 127 static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len) 128 { 129 XenPCIPassthroughState *s = XEN_PT_DEVICE(d); 130 uint32_t val = 0; 131 XenPTRegGroup *reg_grp_entry = NULL; 132 XenPTReg *reg_entry = NULL; 133 int rc = 0; 134 int emul_len = 0; 135 uint32_t find_addr = addr; 136 137 if (xen_pt_pci_config_access_check(d, addr, len)) { 138 goto exit; 139 } 140 141 /* find register group entry */ 142 reg_grp_entry = xen_pt_find_reg_grp(s, addr); 143 if (reg_grp_entry) { 144 /* check 0-Hardwired register group */ 145 if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) { 146 /* no need to emulate, just return 0 */ 147 val = 0; 148 goto exit; 149 } 150 } 151 152 /* read I/O device register value */ 153 rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len); 154 if (rc < 0) { 155 XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc); 156 memset(&val, 0xff, len); 157 } 158 159 /* just return the I/O device register value for 160 * passthrough type register group */ 161 if (reg_grp_entry == NULL) { 162 goto exit; 163 } 164 165 /* adjust the read value to appropriate CFC-CFF window */ 166 val <<= (addr & 3) << 3; 167 emul_len = len; 168 169 /* loop around the guest requested size */ 170 while (emul_len > 0) { 171 /* find register entry to be emulated */ 172 reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr); 173 if (reg_entry) { 174 XenPTRegInfo *reg = reg_entry->reg; 175 uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; 176 uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); 177 uint8_t *ptr_val = NULL; 178 179 valid_mask <<= (find_addr - real_offset) << 3; 180 ptr_val = (uint8_t *)&val + (real_offset & 3); 181 182 /* do emulation based on register size */ 183 switch (reg->size) { 184 case 1: 185 if (reg->u.b.read) { 186 rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask); 187 } 188 break; 189 case 2: 190 if (reg->u.w.read) { 191 rc = reg->u.w.read(s, reg_entry, 192 (uint16_t *)ptr_val, valid_mask); 193 } 194 break; 195 case 4: 196 if (reg->u.dw.read) { 197 rc = reg->u.dw.read(s, reg_entry, 198 (uint32_t *)ptr_val, valid_mask); 199 } 200 break; 201 } 202 203 if (rc < 0) { 204 xen_shutdown_fatal_error("Internal error: Invalid read " 205 "emulation. (%s, rc: %d)\n", 206 __func__, rc); 207 return 0; 208 } 209 210 /* calculate next address to find */ 211 emul_len -= reg->size; 212 if (emul_len > 0) { 213 find_addr = real_offset + reg->size; 214 } 215 } else { 216 /* nothing to do with passthrough type register, 217 * continue to find next byte */ 218 emul_len--; 219 find_addr++; 220 } 221 } 222 223 /* need to shift back before returning them to pci bus emulator */ 224 val >>= ((addr & 3) << 3); 225 226 exit: 227 XEN_PT_LOG_CONFIG(d, addr, val, len); 228 return val; 229 } 230 231 static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, 232 uint32_t val, int len) 233 { 234 XenPCIPassthroughState *s = XEN_PT_DEVICE(d); 235 int index = 0; 236 XenPTRegGroup *reg_grp_entry = NULL; 237 int rc = 0; 238 uint32_t read_val = 0, wb_mask; 239 int emul_len = 0; 240 XenPTReg *reg_entry = NULL; 241 uint32_t find_addr = addr; 242 XenPTRegInfo *reg = NULL; 243 bool wp_flag = false; 244 245 if (xen_pt_pci_config_access_check(d, addr, len)) { 246 return; 247 } 248 249 XEN_PT_LOG_CONFIG(d, addr, val, len); 250 251 /* check unused BAR register */ 252 index = xen_pt_bar_offset_to_index(addr); 253 if ((index >= 0) && (val != 0)) { 254 uint32_t chk = val; 255 256 if (index == PCI_ROM_SLOT) 257 chk |= (uint32_t)~PCI_ROM_ADDRESS_MASK; 258 259 if ((chk != XEN_PT_BAR_ALLF) && 260 (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) { 261 XEN_PT_WARN(d, "Guest attempt to set address to unused " 262 "Base Address Register. (addr: 0x%02x, len: %d)\n", 263 addr, len); 264 } 265 } 266 267 /* find register group entry */ 268 reg_grp_entry = xen_pt_find_reg_grp(s, addr); 269 if (reg_grp_entry) { 270 /* check 0-Hardwired register group */ 271 if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) { 272 /* ignore silently */ 273 XEN_PT_WARN(d, "Access to 0-Hardwired register. " 274 "(addr: 0x%02x, len: %d)\n", addr, len); 275 return; 276 } 277 } 278 279 rc = xen_host_pci_get_block(&s->real_device, addr, 280 (uint8_t *)&read_val, len); 281 if (rc < 0) { 282 XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc); 283 memset(&read_val, 0xff, len); 284 wb_mask = 0; 285 } else { 286 wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); 287 } 288 289 /* pass directly to the real device for passthrough type register group */ 290 if (reg_grp_entry == NULL) { 291 if (!s->permissive) { 292 wb_mask = 0; 293 wp_flag = true; 294 } 295 goto out; 296 } 297 298 memory_region_transaction_begin(); 299 pci_default_write_config(d, addr, val, len); 300 301 /* adjust the read and write value to appropriate CFC-CFF window */ 302 read_val <<= (addr & 3) << 3; 303 val <<= (addr & 3) << 3; 304 emul_len = len; 305 306 /* loop around the guest requested size */ 307 while (emul_len > 0) { 308 /* find register entry to be emulated */ 309 reg_entry = xen_pt_find_reg(reg_grp_entry, find_addr); 310 if (reg_entry) { 311 reg = reg_entry->reg; 312 uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; 313 uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); 314 uint8_t *ptr_val = NULL; 315 uint32_t wp_mask = reg->emu_mask | reg->ro_mask; 316 317 valid_mask <<= (find_addr - real_offset) << 3; 318 ptr_val = (uint8_t *)&val + (real_offset & 3); 319 if (!s->permissive) { 320 wp_mask |= reg->res_mask; 321 } 322 if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { 323 wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) 324 << ((len - emul_len) << 3)); 325 } 326 327 /* do emulation based on register size */ 328 switch (reg->size) { 329 case 1: 330 if (reg->u.b.write) { 331 rc = reg->u.b.write(s, reg_entry, ptr_val, 332 read_val >> ((real_offset & 3) << 3), 333 valid_mask); 334 } 335 break; 336 case 2: 337 if (reg->u.w.write) { 338 rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val, 339 (read_val >> ((real_offset & 3) << 3)), 340 valid_mask); 341 } 342 break; 343 case 4: 344 if (reg->u.dw.write) { 345 rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val, 346 (read_val >> ((real_offset & 3) << 3)), 347 valid_mask); 348 } 349 break; 350 } 351 352 if (rc < 0) { 353 xen_shutdown_fatal_error("Internal error: Invalid write" 354 " emulation. (%s, rc: %d)\n", 355 __func__, rc); 356 return; 357 } 358 359 /* calculate next address to find */ 360 emul_len -= reg->size; 361 if (emul_len > 0) { 362 find_addr = real_offset + reg->size; 363 } 364 } else { 365 /* nothing to do with passthrough type register, 366 * continue to find next byte */ 367 if (!s->permissive) { 368 wb_mask &= ~(0xff << ((len - emul_len) << 3)); 369 /* Unused BARs will make it here, but we don't want to issue 370 * warnings for writes to them (bogus writes get dealt with 371 * above). 372 */ 373 if (index < 0) { 374 wp_flag = true; 375 } 376 } 377 emul_len--; 378 find_addr++; 379 } 380 } 381 382 /* need to shift back before passing them to xen_host_pci_set_block. */ 383 val >>= (addr & 3) << 3; 384 385 memory_region_transaction_commit(); 386 387 out: 388 if (wp_flag && !s->permissive_warned) { 389 s->permissive_warned = true; 390 xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", 391 addr, len * 2, wb_mask); 392 xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n"); 393 xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n"); 394 } 395 for (index = 0; wb_mask; index += len) { 396 /* unknown regs are passed through */ 397 while (!(wb_mask & 0xff)) { 398 index++; 399 wb_mask >>= 8; 400 } 401 len = 0; 402 do { 403 len++; 404 wb_mask >>= 8; 405 } while (wb_mask & 0xff); 406 rc = xen_host_pci_set_block(&s->real_device, addr + index, 407 (uint8_t *)&val + index, len); 408 409 if (rc < 0) { 410 XEN_PT_ERR(d, "xen_host_pci_set_block failed. return value: %d.\n", rc); 411 } 412 } 413 } 414 415 /* register regions */ 416 417 static uint64_t xen_pt_bar_read(void *o, hwaddr addr, 418 unsigned size) 419 { 420 PCIDevice *d = o; 421 /* if this function is called, that probably means that there is a 422 * misconfiguration of the IOMMU. */ 423 XEN_PT_ERR(d, "Should not read BAR through QEMU. @0x"TARGET_FMT_plx"\n", 424 addr); 425 return 0; 426 } 427 static void xen_pt_bar_write(void *o, hwaddr addr, uint64_t val, 428 unsigned size) 429 { 430 PCIDevice *d = o; 431 /* Same comment as xen_pt_bar_read function */ 432 XEN_PT_ERR(d, "Should not write BAR through QEMU. @0x"TARGET_FMT_plx"\n", 433 addr); 434 } 435 436 static const MemoryRegionOps ops = { 437 .endianness = DEVICE_NATIVE_ENDIAN, 438 .read = xen_pt_bar_read, 439 .write = xen_pt_bar_write, 440 }; 441 442 static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd) 443 { 444 int i = 0; 445 XenHostPCIDevice *d = &s->real_device; 446 447 /* Register PIO/MMIO BARs */ 448 for (i = 0; i < PCI_ROM_SLOT; i++) { 449 XenHostPCIIORegion *r = &d->io_regions[i]; 450 uint8_t type; 451 452 if (r->base_addr == 0 || r->size == 0) { 453 continue; 454 } 455 456 s->bases[i].access.u = r->base_addr; 457 458 if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) { 459 type = PCI_BASE_ADDRESS_SPACE_IO; 460 *cmd |= PCI_COMMAND_IO; 461 } else { 462 type = PCI_BASE_ADDRESS_SPACE_MEMORY; 463 if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) { 464 type |= PCI_BASE_ADDRESS_MEM_PREFETCH; 465 } 466 if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) { 467 type |= PCI_BASE_ADDRESS_MEM_TYPE_64; 468 } 469 *cmd |= PCI_COMMAND_MEMORY; 470 } 471 472 memory_region_init_io(&s->bar[i], OBJECT(s), &ops, &s->dev, 473 "xen-pci-pt-bar", r->size); 474 pci_register_bar(&s->dev, i, type, &s->bar[i]); 475 476 XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64 477 " base_addr=0x%08"PRIx64" type: %#x)\n", 478 i, r->size, r->base_addr, type); 479 } 480 481 /* Register expansion ROM address */ 482 if (d->rom.base_addr && d->rom.size) { 483 uint32_t bar_data = 0; 484 485 /* Re-set BAR reported by OS, otherwise ROM can't be read. */ 486 if (xen_host_pci_get_long(d, PCI_ROM_ADDRESS, &bar_data)) { 487 return 0; 488 } 489 if ((bar_data & PCI_ROM_ADDRESS_MASK) == 0) { 490 bar_data |= d->rom.base_addr & PCI_ROM_ADDRESS_MASK; 491 xen_host_pci_set_long(d, PCI_ROM_ADDRESS, bar_data); 492 } 493 494 s->bases[PCI_ROM_SLOT].access.maddr = d->rom.base_addr; 495 496 memory_region_init_io(&s->rom, OBJECT(s), &ops, &s->dev, 497 "xen-pci-pt-rom", d->rom.size); 498 pci_register_bar(&s->dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_MEM_PREFETCH, 499 &s->rom); 500 501 XEN_PT_LOG(&s->dev, "Expansion ROM registered (size=0x%08"PRIx64 502 " base_addr=0x%08"PRIx64")\n", 503 d->rom.size, d->rom.base_addr); 504 } 505 506 xen_pt_register_vga_regions(d); 507 return 0; 508 } 509 510 /* region mapping */ 511 512 static int xen_pt_bar_from_region(XenPCIPassthroughState *s, MemoryRegion *mr) 513 { 514 int i = 0; 515 516 for (i = 0; i < PCI_NUM_REGIONS - 1; i++) { 517 if (mr == &s->bar[i]) { 518 return i; 519 } 520 } 521 if (mr == &s->rom) { 522 return PCI_ROM_SLOT; 523 } 524 return -1; 525 } 526 527 /* 528 * This function checks if an io_region overlaps an io_region from another 529 * device. The io_region to check is provided with (addr, size and type) 530 * A callback can be provided and will be called for every region that is 531 * overlapped. 532 * The return value indicates if the region is overlappsed */ 533 struct CheckBarArgs { 534 XenPCIPassthroughState *s; 535 pcibus_t addr; 536 pcibus_t size; 537 uint8_t type; 538 bool rc; 539 }; 540 static void xen_pt_check_bar_overlap(PCIBus *bus, PCIDevice *d, void *opaque) 541 { 542 struct CheckBarArgs *arg = opaque; 543 XenPCIPassthroughState *s = arg->s; 544 uint8_t type = arg->type; 545 int i; 546 547 if (d->devfn == s->dev.devfn) { 548 return; 549 } 550 551 /* xxx: This ignores bridges. */ 552 for (i = 0; i < PCI_NUM_REGIONS; i++) { 553 const PCIIORegion *r = &d->io_regions[i]; 554 555 if (!r->size) { 556 continue; 557 } 558 if ((type & PCI_BASE_ADDRESS_SPACE_IO) 559 != (r->type & PCI_BASE_ADDRESS_SPACE_IO)) { 560 continue; 561 } 562 563 if (ranges_overlap(arg->addr, arg->size, r->addr, r->size)) { 564 XEN_PT_WARN(&s->dev, 565 "Overlapped to device [%02x:%02x.%d] Region: %i" 566 " (addr: %#"FMT_PCIBUS", len: %#"FMT_PCIBUS")\n", 567 pci_bus_num(bus), PCI_SLOT(d->devfn), 568 PCI_FUNC(d->devfn), i, r->addr, r->size); 569 arg->rc = true; 570 } 571 } 572 } 573 574 static void xen_pt_region_update(XenPCIPassthroughState *s, 575 MemoryRegionSection *sec, bool adding) 576 { 577 PCIDevice *d = &s->dev; 578 MemoryRegion *mr = sec->mr; 579 int bar = -1; 580 int rc; 581 int op = adding ? DPCI_ADD_MAPPING : DPCI_REMOVE_MAPPING; 582 struct CheckBarArgs args = { 583 .s = s, 584 .addr = sec->offset_within_address_space, 585 .size = int128_get64(sec->size), 586 .rc = false, 587 }; 588 589 bar = xen_pt_bar_from_region(s, mr); 590 if (bar == -1 && (!s->msix || &s->msix->mmio != mr)) { 591 return; 592 } 593 594 if (s->msix && &s->msix->mmio == mr) { 595 if (adding) { 596 s->msix->mmio_base_addr = sec->offset_within_address_space; 597 rc = xen_pt_msix_update_remap(s, s->msix->bar_index); 598 } 599 return; 600 } 601 602 args.type = d->io_regions[bar].type; 603 pci_for_each_device(d->bus, pci_bus_num(d->bus), 604 xen_pt_check_bar_overlap, &args); 605 if (args.rc) { 606 XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS 607 ", len: %#"FMT_PCIBUS") is overlapped.\n", 608 bar, sec->offset_within_address_space, 609 int128_get64(sec->size)); 610 } 611 612 if (d->io_regions[bar].type & PCI_BASE_ADDRESS_SPACE_IO) { 613 uint32_t guest_port = sec->offset_within_address_space; 614 uint32_t machine_port = s->bases[bar].access.pio_base; 615 uint32_t size = int128_get64(sec->size); 616 rc = xc_domain_ioport_mapping(xen_xc, xen_domid, 617 guest_port, machine_port, size, 618 op); 619 if (rc) { 620 XEN_PT_ERR(d, "%s ioport mapping failed! (err: %i)\n", 621 adding ? "create new" : "remove old", errno); 622 } 623 } else { 624 pcibus_t guest_addr = sec->offset_within_address_space; 625 pcibus_t machine_addr = s->bases[bar].access.maddr 626 + sec->offset_within_region; 627 pcibus_t size = int128_get64(sec->size); 628 rc = xc_domain_memory_mapping(xen_xc, xen_domid, 629 XEN_PFN(guest_addr + XC_PAGE_SIZE - 1), 630 XEN_PFN(machine_addr + XC_PAGE_SIZE - 1), 631 XEN_PFN(size + XC_PAGE_SIZE - 1), 632 op); 633 if (rc) { 634 XEN_PT_ERR(d, "%s mem mapping failed! (err: %i)\n", 635 adding ? "create new" : "remove old", errno); 636 } 637 } 638 } 639 640 static void xen_pt_region_add(MemoryListener *l, MemoryRegionSection *sec) 641 { 642 XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, 643 memory_listener); 644 645 memory_region_ref(sec->mr); 646 xen_pt_region_update(s, sec, true); 647 } 648 649 static void xen_pt_region_del(MemoryListener *l, MemoryRegionSection *sec) 650 { 651 XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, 652 memory_listener); 653 654 xen_pt_region_update(s, sec, false); 655 memory_region_unref(sec->mr); 656 } 657 658 static void xen_pt_io_region_add(MemoryListener *l, MemoryRegionSection *sec) 659 { 660 XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, 661 io_listener); 662 663 memory_region_ref(sec->mr); 664 xen_pt_region_update(s, sec, true); 665 } 666 667 static void xen_pt_io_region_del(MemoryListener *l, MemoryRegionSection *sec) 668 { 669 XenPCIPassthroughState *s = container_of(l, XenPCIPassthroughState, 670 io_listener); 671 672 xen_pt_region_update(s, sec, false); 673 memory_region_unref(sec->mr); 674 } 675 676 static const MemoryListener xen_pt_memory_listener = { 677 .region_add = xen_pt_region_add, 678 .region_del = xen_pt_region_del, 679 .priority = 10, 680 }; 681 682 static const MemoryListener xen_pt_io_listener = { 683 .region_add = xen_pt_io_region_add, 684 .region_del = xen_pt_io_region_del, 685 .priority = 10, 686 }; 687 688 static void 689 xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s, 690 XenHostPCIDevice *dev) 691 { 692 uint16_t gpu_dev_id; 693 PCIDevice *d = &s->dev; 694 695 gpu_dev_id = dev->device_id; 696 igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id); 697 } 698 699 /* destroy. */ 700 static void xen_pt_destroy(PCIDevice *d) { 701 702 XenPCIPassthroughState *s = XEN_PT_DEVICE(d); 703 XenHostPCIDevice *host_dev = &s->real_device; 704 uint8_t machine_irq = s->machine_irq; 705 uint8_t intx; 706 int rc; 707 708 if (machine_irq && !xen_host_pci_device_closed(&s->real_device)) { 709 intx = xen_pt_pci_intx(s); 710 rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq, 711 PT_IRQ_TYPE_PCI, 712 pci_bus_num(d->bus), 713 PCI_SLOT(s->dev.devfn), 714 intx, 715 0 /* isa_irq */); 716 if (rc < 0) { 717 XEN_PT_ERR(d, "unbinding of interrupt INT%c failed." 718 " (machine irq: %i, err: %d)" 719 " But bravely continuing on..\n", 720 'a' + intx, machine_irq, errno); 721 } 722 } 723 724 /* N.B. xen_pt_config_delete takes care of freeing them. */ 725 if (s->msi) { 726 xen_pt_msi_disable(s); 727 } 728 if (s->msix) { 729 xen_pt_msix_disable(s); 730 } 731 732 if (machine_irq) { 733 xen_pt_mapped_machine_irq[machine_irq]--; 734 735 if (xen_pt_mapped_machine_irq[machine_irq] == 0) { 736 rc = xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq); 737 738 if (rc < 0) { 739 XEN_PT_ERR(d, "unmapping of interrupt %i failed. (err: %d)" 740 " But bravely continuing on..\n", 741 machine_irq, errno); 742 } 743 } 744 s->machine_irq = 0; 745 } 746 747 /* delete all emulated config registers */ 748 xen_pt_config_delete(s); 749 750 xen_pt_unregister_vga_regions(host_dev); 751 752 if (s->listener_set) { 753 memory_listener_unregister(&s->memory_listener); 754 memory_listener_unregister(&s->io_listener); 755 s->listener_set = false; 756 } 757 if (!xen_host_pci_device_closed(&s->real_device)) { 758 xen_host_pci_device_put(&s->real_device); 759 } 760 } 761 /* init */ 762 763 static int xen_pt_initfn(PCIDevice *d) 764 { 765 XenPCIPassthroughState *s = XEN_PT_DEVICE(d); 766 int rc = 0; 767 uint8_t machine_irq = 0, scratch; 768 uint16_t cmd = 0; 769 int pirq = XEN_PT_UNASSIGNED_PIRQ; 770 771 /* register real device */ 772 XEN_PT_LOG(d, "Assigning real physical device %02x:%02x.%d" 773 " to devfn %#x\n", 774 s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function, 775 s->dev.devfn); 776 777 rc = xen_host_pci_device_get(&s->real_device, 778 s->hostaddr.domain, s->hostaddr.bus, 779 s->hostaddr.slot, s->hostaddr.function); 780 if (rc) { 781 XEN_PT_ERR(d, "Failed to \"open\" the real pci device. rc: %i\n", rc); 782 return -1; 783 } 784 785 s->is_virtfn = s->real_device.is_virtfn; 786 if (s->is_virtfn) { 787 XEN_PT_LOG(d, "%04x:%02x:%02x.%d is a SR-IOV Virtual Function\n", 788 s->real_device.domain, s->real_device.bus, 789 s->real_device.dev, s->real_device.func); 790 } 791 792 /* Initialize virtualized PCI configuration (Extended 256 Bytes) */ 793 memset(d->config, 0, PCI_CONFIG_SPACE_SIZE); 794 795 s->memory_listener = xen_pt_memory_listener; 796 s->io_listener = xen_pt_io_listener; 797 798 /* Setup VGA bios for passthrough GFX */ 799 if ((s->real_device.domain == 0) && (s->real_device.bus == 0) && 800 (s->real_device.dev == 2) && (s->real_device.func == 0)) { 801 if (!is_igd_vga_passthrough(&s->real_device)) { 802 XEN_PT_ERR(d, "Need to enable igd-passthru if you're trying" 803 " to passthrough IGD GFX.\n"); 804 xen_host_pci_device_put(&s->real_device); 805 return -1; 806 } 807 808 if (xen_pt_setup_vga(s, &s->real_device) < 0) { 809 XEN_PT_ERR(d, "Setup VGA BIOS of passthrough GFX failed!\n"); 810 xen_host_pci_device_put(&s->real_device); 811 return -1; 812 } 813 814 /* Register ISA bridge for passthrough GFX. */ 815 xen_igd_passthrough_isa_bridge_create(s, &s->real_device); 816 } 817 818 /* Handle real device's MMIO/PIO BARs */ 819 xen_pt_register_regions(s, &cmd); 820 821 /* reinitialize each config register to be emulated */ 822 rc = xen_pt_config_init(s); 823 if (rc) { 824 XEN_PT_ERR(d, "PCI Config space initialisation failed.\n"); 825 goto err_out; 826 } 827 828 /* Bind interrupt */ 829 rc = xen_host_pci_get_byte(&s->real_device, PCI_INTERRUPT_PIN, &scratch); 830 if (rc) { 831 XEN_PT_ERR(d, "Failed to read PCI_INTERRUPT_PIN! (rc:%d)\n", rc); 832 goto err_out; 833 } 834 if (!scratch) { 835 XEN_PT_LOG(d, "no pin interrupt\n"); 836 goto out; 837 } 838 839 machine_irq = s->real_device.irq; 840 rc = xc_physdev_map_pirq(xen_xc, xen_domid, machine_irq, &pirq); 841 842 if (rc < 0) { 843 XEN_PT_ERR(d, "Mapping machine irq %u to pirq %i failed, (err: %d)\n", 844 machine_irq, pirq, errno); 845 846 /* Disable PCI intx assertion (turn on bit10 of devctl) */ 847 cmd |= PCI_COMMAND_INTX_DISABLE; 848 machine_irq = 0; 849 s->machine_irq = 0; 850 } else { 851 machine_irq = pirq; 852 s->machine_irq = pirq; 853 xen_pt_mapped_machine_irq[machine_irq]++; 854 } 855 856 /* bind machine_irq to device */ 857 if (machine_irq != 0) { 858 uint8_t e_intx = xen_pt_pci_intx(s); 859 860 rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq, 861 pci_bus_num(d->bus), 862 PCI_SLOT(d->devfn), 863 e_intx); 864 if (rc < 0) { 865 XEN_PT_ERR(d, "Binding of interrupt %i failed! (err: %d)\n", 866 e_intx, errno); 867 868 /* Disable PCI intx assertion (turn on bit10 of devctl) */ 869 cmd |= PCI_COMMAND_INTX_DISABLE; 870 xen_pt_mapped_machine_irq[machine_irq]--; 871 872 if (xen_pt_mapped_machine_irq[machine_irq] == 0) { 873 if (xc_physdev_unmap_pirq(xen_xc, xen_domid, machine_irq)) { 874 XEN_PT_ERR(d, "Unmapping of machine interrupt %i failed!" 875 " (err: %d)\n", machine_irq, errno); 876 } 877 } 878 s->machine_irq = 0; 879 } 880 } 881 882 out: 883 if (cmd) { 884 uint16_t val; 885 886 rc = xen_host_pci_get_word(&s->real_device, PCI_COMMAND, &val); 887 if (rc) { 888 XEN_PT_ERR(d, "Failed to read PCI_COMMAND! (rc: %d)\n", rc); 889 goto err_out; 890 } else { 891 val |= cmd; 892 rc = xen_host_pci_set_word(&s->real_device, PCI_COMMAND, val); 893 if (rc) { 894 XEN_PT_ERR(d, "Failed to write PCI_COMMAND val=0x%x!(rc: %d)\n", 895 val, rc); 896 goto err_out; 897 } 898 } 899 } 900 901 memory_listener_register(&s->memory_listener, &s->dev.bus_master_as); 902 memory_listener_register(&s->io_listener, &address_space_io); 903 s->listener_set = true; 904 XEN_PT_LOG(d, 905 "Real physical device %02x:%02x.%d registered successfully!\n", 906 s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function); 907 908 return 0; 909 910 err_out: 911 xen_pt_destroy(d); 912 assert(rc); 913 return rc; 914 } 915 916 static void xen_pt_unregister_device(PCIDevice *d) 917 { 918 xen_pt_destroy(d); 919 } 920 921 static Property xen_pci_passthrough_properties[] = { 922 DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr), 923 DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false), 924 DEFINE_PROP_END_OF_LIST(), 925 }; 926 927 static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data) 928 { 929 DeviceClass *dc = DEVICE_CLASS(klass); 930 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 931 932 k->init = xen_pt_initfn; 933 k->exit = xen_pt_unregister_device; 934 k->config_read = xen_pt_pci_read_config; 935 k->config_write = xen_pt_pci_write_config; 936 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 937 dc->desc = "Assign an host PCI device with Xen"; 938 dc->props = xen_pci_passthrough_properties; 939 }; 940 941 static const TypeInfo xen_pci_passthrough_info = { 942 .name = TYPE_XEN_PT_DEVICE, 943 .parent = TYPE_PCI_DEVICE, 944 .instance_size = sizeof(XenPCIPassthroughState), 945 .class_init = xen_pci_passthrough_class_init, 946 }; 947 948 static void xen_pci_passthrough_register_types(void) 949 { 950 type_register_static(&xen_pci_passthrough_info); 951 } 952 953 type_init(xen_pci_passthrough_register_types) 954