Revision 96adc5c7

b/hw/vfio_pci.c
1506 1506
    return next - pos;
1507 1507
}
1508 1508

  
1509
static void vfio_set_word_bits(uint8_t *buf, uint16_t val, uint16_t mask)
1510
{
1511
    pci_set_word(buf, (pci_get_word(buf) & ~mask) | val);
1512
}
1513

  
1514
static void vfio_add_emulated_word(VFIODevice *vdev, int pos,
1515
                                   uint16_t val, uint16_t mask)
1516
{
1517
    vfio_set_word_bits(vdev->pdev.config + pos, val, mask);
1518
    vfio_set_word_bits(vdev->pdev.wmask + pos, ~mask, mask);
1519
    vfio_set_word_bits(vdev->emulated_config_bits + pos, mask, mask);
1520
}
1521

  
1522
static void vfio_set_long_bits(uint8_t *buf, uint32_t val, uint32_t mask)
1523
{
1524
    pci_set_long(buf, (pci_get_long(buf) & ~mask) | val);
1525
}
1526

  
1527
static void vfio_add_emulated_long(VFIODevice *vdev, int pos,
1528
                                   uint32_t val, uint32_t mask)
1529
{
1530
    vfio_set_long_bits(vdev->pdev.config + pos, val, mask);
1531
    vfio_set_long_bits(vdev->pdev.wmask + pos, ~mask, mask);
1532
    vfio_set_long_bits(vdev->emulated_config_bits + pos, mask, mask);
1533
}
1534

  
1535
static int vfio_setup_pcie_cap(VFIODevice *vdev, int pos, uint8_t size)
1536
{
1537
    uint16_t flags;
1538
    uint8_t type;
1539

  
1540
    flags = pci_get_word(vdev->pdev.config + pos + PCI_CAP_FLAGS);
1541
    type = (flags & PCI_EXP_FLAGS_TYPE) >> 4;
1542

  
1543
    if (type != PCI_EXP_TYPE_ENDPOINT &&
1544
        type != PCI_EXP_TYPE_LEG_END &&
1545
        type != PCI_EXP_TYPE_RC_END) {
1546

  
1547
        error_report("vfio: Assignment of PCIe type 0x%x "
1548
                     "devices is not currently supported", type);
1549
        return -EINVAL;
1550
    }
1551

  
1552
    if (!pci_bus_is_express(vdev->pdev.bus)) {
1553
        /*
1554
         * Use express capability as-is on PCI bus.  It doesn't make much
1555
         * sense to even expose, but some drivers (ex. tg3) depend on it
1556
         * and guests don't seem to be particular about it.  We'll need
1557
         * to revist this or force express devices to express buses if we
1558
         * ever expose an IOMMU to the guest.
1559
         */
1560
    } else if (pci_bus_is_root(vdev->pdev.bus)) {
1561
        /*
1562
         * On a Root Complex bus Endpoints become Root Complex Integrated
1563
         * Endpoints, which changes the type and clears the LNK & LNK2 fields.
1564
         */
1565
        if (type == PCI_EXP_TYPE_ENDPOINT) {
1566
            vfio_add_emulated_word(vdev, pos + PCI_CAP_FLAGS,
1567
                                   PCI_EXP_TYPE_RC_END << 4,
1568
                                   PCI_EXP_FLAGS_TYPE);
1569

  
1570
            /* Link Capabilities, Status, and Control goes away */
1571
            if (size > PCI_EXP_LNKCTL) {
1572
                vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP, 0, ~0);
1573
                vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0);
1574
                vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA, 0, ~0);
1575

  
1576
#ifndef PCI_EXP_LNKCAP2
1577
#define PCI_EXP_LNKCAP2 44
1578
#endif
1579
#ifndef PCI_EXP_LNKSTA2
1580
#define PCI_EXP_LNKSTA2 50
1581
#endif
1582
                /* Link 2 Capabilities, Status, and Control goes away */
1583
                if (size > PCI_EXP_LNKCAP2) {
1584
                    vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP2, 0, ~0);
1585
                    vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL2, 0, ~0);
1586
                    vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA2, 0, ~0);
1587
                }
1588
            }
1589

  
1590
        } else if (type == PCI_EXP_TYPE_LEG_END) {
1591
            /*
1592
             * Legacy endpoints don't belong on the root complex.  Windows
1593
             * seems to be happier with devices if we skip the capability.
1594
             */
1595
            return 0;
1596
        }
1597

  
1598
    } else {
1599
        /*
1600
         * Convert Root Complex Integrated Endpoints to regular endpoints.
1601
         * These devices don't support LNK/LNK2 capabilities, so make them up.
1602
         */
1603
        if (type == PCI_EXP_TYPE_RC_END) {
1604
            vfio_add_emulated_word(vdev, pos + PCI_CAP_FLAGS,
1605
                                   PCI_EXP_TYPE_ENDPOINT << 4,
1606
                                   PCI_EXP_FLAGS_TYPE);
1607
            vfio_add_emulated_long(vdev, pos + PCI_EXP_LNKCAP,
1608
                                   PCI_EXP_LNK_MLW_1 | PCI_EXP_LNK_LS_25, ~0);
1609
            vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKCTL, 0, ~0);
1610
        }
1611

  
1612
        /* Mark the Link Status bits as emulated to allow virtual negotiation */
1613
        vfio_add_emulated_word(vdev, pos + PCI_EXP_LNKSTA,
1614
                               pci_get_word(vdev->pdev.config + pos +
1615
                                            PCI_EXP_LNKSTA),
1616
                               PCI_EXP_LNKCAP_MLW | PCI_EXP_LNKCAP_SLS);
1617
    }
1618

  
1619
    pos = pci_add_capability(&vdev->pdev, PCI_CAP_ID_EXP, pos, size);
1620
    if (pos >= 0) {
1621
        vdev->pdev.exp.exp_cap = pos;
1622
    }
1623

  
1624
    return pos;
1625
}
1626

  
1509 1627
static int vfio_add_std_cap(VFIODevice *vdev, uint8_t pos)
1510 1628
{
1511 1629
    PCIDevice *pdev = &vdev->pdev;
......
1536 1654
            return ret;
1537 1655
        }
1538 1656
    } else {
1539
        pdev->config[PCI_CAPABILITY_LIST] = 0; /* Begin the rebuild */
1657
        /* Begin the rebuild, use QEMU emulated list bits */
1658
        pdev->config[PCI_CAPABILITY_LIST] = 0;
1659
        vdev->emulated_config_bits[PCI_CAPABILITY_LIST] = 0xff;
1660
        vdev->emulated_config_bits[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
1540 1661
    }
1541 1662

  
1663
    /* Use emulated next pointer to allow dropping caps */
1664
    pci_set_byte(vdev->emulated_config_bits + pos + 1, 0xff);
1665

  
1542 1666
    switch (cap_id) {
1543 1667
    case PCI_CAP_ID_MSI:
1544 1668
        ret = vfio_setup_msi(vdev, pos);
1545 1669
        break;
1670
    case PCI_CAP_ID_EXP:
1671
        ret = vfio_setup_pcie_cap(vdev, pos, size);
1672
        break;
1546 1673
    case PCI_CAP_ID_MSIX:
1547 1674
        ret = vfio_setup_msix(vdev, pos);
1548 1675
        break;

Also available in: Unified diff